hit2739
好题,回路的问题一般都要转化为度数来做
若原图的基图不连通,或者存在某个点的入度或出度为0则无解。
统计所有点的入度出度之差di
对于di>0的点,加边(s,i,di,0);
对于di<0的点,加边(i,t,-di,0);
对原图中的每条边(i,j),在网络中加边(i,j,inf,边权),
最小费用流的解加上原图所有边权和即为答案。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std;
struct way{int po,next,flow,cost;} e[];
const int inf=;
int pre[],p[],cur[],d[],fa[],cd[],rd[],q[];
bool v[];
int n,m,len,t; int getf(int x)
{
if (fa[x]!=x) fa[x]=getf(fa[x]);
return fa[x];
} bool check()
{
for (int i=; i<=n; i++)
if (!rd[i]||!cd[i]||getf(i)!=getf()) return ;
return ;
} void add(int x,int y,int f,int c)
{
e[++len].po=y;
e[len].flow=f;
e[len].cost=c;
e[len].next=p[x];
p[x]=len;
} void build(int x,int y, int f, int c)
{
add(x,y,f,c);
add(y,x,,-c);
} bool spfa()
{
int f=,r=;
for (int i=; i<=t; i++) d[i]=inf;
memset(v,false,sizeof(v));
d[]=; q[]=;
while (f<=r)
{
int x=q[f++];
v[x]=;
for (int i=p[x]; i!=-; i=e[i].next)
{
int y=e[i].po;
if (e[i].flow&&d[x]+e[i].cost<d[y])
{
d[y]=d[x]+e[i].cost;
pre[y]=x; cur[y]=i;
if (!v[y])
{
q[++r]=y;
v[y]=;
}
}
}
}
return d[n]<inf;
} int mincost()
{
int j,s=;
while (spfa())
{
int neck=inf;
for (int i=t; i; i=pre[i])
{
j=cur[i];
neck=min(neck,e[j].flow);
}
s+=d[t]*neck;
for (int i=t; i; i=pre[i])
{
j=cur[i];
e[j].flow-=neck;
e[j^].flow+=neck;
}
}
return s;
} int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d%d",&n,&m);
memset(p,,sizeof(p)); len=-;
memset(rd,,sizeof(rd));
memset(cd,,sizeof(cd));
for (int i=; i<=n; i++) fa[i]=i;
int ans=;
for (int i=; i<=m; i++)
{
int x,y,u,v,z;
scanf("%d%d%d",&x,&y,&z);
cd[++x]++;rd[++y]++;
build(x,y,inf,z);
u=getf(x),v=getf(y);
if (u!=v) fa[u]=v;
ans+=z;
}
if (!check())
{
puts("-1");
continue;
}
t=n+;
for (int i=; i<=n; i++)
if (rd[i]>cd[i]) build(,i,rd[i]-cd[i],);
else build(i,t,cd[i]-rd[i],);
ans+=mincost();
printf("%d\n",ans);
}
}
hit2739的更多相关文章
- HIT2739 The Chinese Postman Problem(最小费用最大流)
题目大概说给一张有向图,要从0点出发返回0点且每条边至少都要走过一次,求走的最短路程. 经典的CPP问题,解法就是加边构造出欧拉回路,一个有向图存在欧拉回路的充分必要条件是基图连通且所有点入度等于出度 ...
随机推荐
- Java空指针异常解决方法
Throwable是所有错误或异常的超类,只有当对象是这个类的实例时才能通过Java虚拟机或者Java throw语句抛出. 当Java运行环境发出异常时,会寻找处理该异常的catch块,找到对应的c ...
- Linux笔记二
用户和组 添加一个tom用户,设置它属于users组,并添加注释信息分步完成:useradd tom usermod -g users tom usermod -c "hr tom" ...
- Struts1之logic标签
logic是Struts1中的逻辑标签 <%@ taglib prefix="logic" uri="http://struts.apache.org/tags-l ...
- 你试过不用if写代码吗?
我在教新手编程时,喜欢给他们一些小小的挑战,比如:不使用if语句(或者三元运算符.switch语句等)解决一些编程问题.这样做有什么意义吗?事实上,它可以迫使你从不同的角度寻找解决方法,也许可以找到更 ...
- AdjustTokenPrivileges启用权限
原文链接地址:http://blog.csdn.net/xbgprogrammer/article/details/7276760 我们有很多操作需要用到OpenProcess函数,而为了使程序 ...
- URAL1696 Salary for Robots
题目戳这里. 最长下降子序列单调队列求法. \(f_{i,j,k}\)表示考虑前\(i\)个数,\(g_1 = j,g_2 = k\)的方案数.转移: \[f_{i,j,k} = \sum_{p = ...
- Event loop的macro task和micro task
macrotask在一些文章中也被直接称为task. 一个宿主环境只有一个事件循环,但可以有多个任务队列.宏任务队列(macro task)与微任务队列(micro task)就是其中之二. 每次事件 ...
- JQuery用鼠标选文字来发新浪微博
最近注意到新浪博客有个小功能,就是当鼠标选中一段文字时会浮现一个小图片,点击这个图片可以把选中内容发送到新浪微博,一时兴起昨晚就写了一个Demo玩了一下,代码超简单,没优化,有兴趣的朋友可以自己改进. ...
- [bzoj 2818]欧拉函数
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2818 枚举最大公约数,对于每一个质数p,只需要求出1<=x,y<=(n/p)范 ...
- org.apache.http.conn.HttpHostConnectException: Connection to xxx refused.
if you are using emulator to run your app for local server. mention the local ip as 10.0.2.2 and hav ...