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问题,解法就是加边构造出欧拉回路,一个有向图存在欧拉回路的充分必要条件是基图连通且所有点入度等于出度 ...
随机推荐
- B - 整数区间
B - 整数区间 Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others) Problem Descr ...
- PAT 甲级 1015 Reversible Primes
https://pintia.cn/problem-sets/994805342720868352/problems/994805495863296000 A reversible prime in ...
- Spark分布式执行原理
Spark分布式执行原理 让代码分布式运行是所有分布式计算框架需要解决的最基本的问题. Spark是大数据领域中相当火热的计算框架,在大数据分析领域有一统江湖的趋势,网上对于Spark源码分析的文章有 ...
- 【bzoj4052】[Cerc2013]Magical GCD 暴力
题目描述 给出一个长度在 100 000 以内的正整数序列,大小不超过 10^12. 求一个连续子序列,使得在所有的连续子序列中,它们的GCD值乘以它们的长度最大. 样例输入 1 5 30 60 2 ...
- BZOJ1857 [Scoi2010]传送带 【三分法】
题目链接 BZOJ1857 题解 画画图就发现实际上是在\(AB\)上和\(CD\)上分别选两个点\(E\),\(F\),使得\(t_{AE} + t_{EF} + t_{FD}\)最小 然后猜想到当 ...
- 论文笔记《Spatial Memory for Context Reasoning in Object Detection》
好久不写论文笔记了,不是没看,而是很少看到好的或者说值得记的了,今天被xinlei这篇paper炸了出来,这篇被据老大说xinlei自称idea of the year,所以看的时候还是很认真的,然后 ...
- Codeforces Round #510 (Div. 2) D. Petya and Array(树状数组)
D. Petya and Array 题目链接:https://codeforces.com/contest/1042/problem/D 题意: 给出n个数,问一共有多少个区间,满足区间和小于t. ...
- ActiveMQ(2) ActiveMQ创建HelloWorld
启动ActiveMQ: 请参见:ActiveMQ(1) 初识ActiveMQ 创建Maven工程: pom文件: <project xmlns="http://maven.apache ...
- AQS同步组件及ReentrantLock和synchronized的区别
AQS同步组件 CountDownLatch(只有一个线程对他进行操作): 主线程必须在启动其它线程后立即调用await()方法.这样主线程的操作就会在这个方法上阻塞,直到其它线程完成各自的任务. S ...
- noip2013 提高组
T1 转圈游戏 题目传送门 果不其然 第一题还是模拟题 一波快速幂解决问题 #include<cstdio> #include<cstring> #include<alg ...