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问题,解法就是加边构造出欧拉回路,一个有向图存在欧拉回路的充分必要条件是基图连通且所有点入度等于出度 ...
随机推荐
- Python创建目录文件夹
Python对文件的操作还算是方便的,只需要包含os模块进来,使用相关函数即可实现目录的创建. 主要涉及到三个函数 1.os.path.exists(path) 判断一个目录是否存在 2.os.mak ...
- WebService使用介绍(三)
jax-ws开发深入 JAX-WS注解 注解说明 WebService的注解都位于javax.jws包下: @WebService-定义服务,在public class上边 targetNamespa ...
- ES mapping的写入与查看
Elasticsearch索引mapping的写入.查看与修改 https://blog.csdn.net/napoay/article/details/52012249 首先创建一个索引: curl ...
- Java —— Reflect反射机制
JAVA反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制. ...
- 洛谷 P2893 [USACO08FEB]修路Making the Grade 解题报告
P2893 [USACO08FEB]修路Making the Grade 题目描述 A straight dirt road connects two fields on FJ's farm, but ...
- JS Cookie相关操作
function setCookie(cookieName, cookieValue, expires) { // 设置Cookie function getCookieName(cookieName ...
- pmap用法小计
By francis_hao Aug 4,2017 pmap-报告进程的内存映射. 概要 pmap [options] pid [...] 描述 pmap命令用来报告一个或多个进程的 ...
- PAT团体程序设计大赛---(模拟)
L1-1 古风排版(20 分) 中国的古人写文字,是从右向左竖向排版的.本题就请你编写程序,把一段文字按古风排版. 输入格式: 输入在第一行给出一个正整数N(<100),是每一列的字符数.第二行 ...
- hadoop 架构
- barba 页面渲染
a.css html, body { padding:; margin: 0 } ol.menu { width: 100%; text-align: left; padding: 0 !import ...