就是求哪些边在最大流上满流,也就是找割边。把0作为t点,s向所有的1~n连流量为inf的边,其他的边按照流量连。跑一遍最大流,从s顺着有残余流量的正向边dfs打标记fr,从t顺着正向边有残余流量的反向边dfs打标记to,那么满足条件的边就是两端点分别有fr和to标记并且满流(这里只考虑正向边),因为这意味着在这条边上增加流量就可以再流一条增广路。

注意一下输出格式,行末不能有空格。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int N=205,inf=1e9,L=2005;
int n,m,l,h[N],cnt=1,le[N],s,t,ans[L];
bool fr[L],to[L];
struct qwe
{
int ne,no,to,v;
}e[N*N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void add(int u,int v,int w)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].no=u;
e[cnt].to=v;
e[cnt].v=w;
h[u]=cnt;
}
void ins(int u,int v,int w)
{
add(u,v,w);
add(v,u,0);
}
bool bfs()
{
queue<int>q;
memset(le,0,sizeof(le));
le[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=h[u];i;i=e[i].ne)
if(e[i].v>0&&!le[e[i].to])
{
le[e[i].to]=le[u]+1;
q.push(e[i].to);
}
}
return le[t];
}
int dfs(int u,int f)
{
if(u==t||!f)
return f;
int us=0;
for(int i=h[u];i&&us<f;i=e[i].ne)
if(le[e[i].to]==le[u]+1&&e[i].v>0)
{
int d=dfs(e[i].to,min(e[i].v,f-us));
e[i].v-=d;
e[i^1].v+=d;
us+=d;
}
if(!us)
le[u]=0;
return us;
}
int dinic()
{
int re=0;
while(bfs())
re+=dfs(s,inf);
return re;
}
void dfs1(int u)
{
fr[u]=1;
for(int i=h[u];i;i=e[i].ne)
if(!fr[e[i].to]&&e[i].v!=0)
dfs1(e[i].to);
}
void dfs2(int u)
{
to[u]=1;
for(int i=h[u];i;i=e[i].ne)
if(!to[e[i].to]&&e[i^1].v!=0)
dfs2(e[i].to);
}
int main()
{
while(1)
{
n=read(),m=read(),l=read();
if(n==0)
break;
s=n+m+1,t=0;
memset(fr,0,sizeof(fr));
memset(to,0,sizeof(to));
memset(h,0,sizeof(h));
cnt=1;ans[0]=0;
for(int i=1;i<=l;i++)
{
int x=read(),y=read(),z=read();
ins(x,y,z);
}
for(int i=1;i<=n;i++)
ins(s,i,inf);
dinic();
dfs1(s);
dfs2(t);
for(int i=1;i<=l;i++)
if(fr[e[i<<1].no]&&to[e[i<<1].to]&&e[i<<1].v==0)
ans[++ans[0]]=i;
if(ans[0])
{
printf("%d",ans[1]);;
for(int i=2;i<=ans[0];i++)
printf(" %d",ans[i]);
}
printf("\n");
}
return 0;
}

zoj 2532 Internship【最小割】的更多相关文章

  1. ZOJ 2532 网络流最小割

    求最小割的问题. 题意:已知网络中有n个源点,m的中转站(也就是节点),一个汇点(编号为0).给出网络,求一些边(增大这个边就可以增大汇点流量的边). 思路:一开始代码只找了有流=0就加入输出数组的情 ...

  2. ZOJ 2532 Internship

    Internship Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Original ID: ...

  3. zoj 2587 判断最小割的唯一性

    算法: 先求出残量网络,计算出从src能够到的点集A,再求出能够到dst的点集B,如果所有点都被访问到了,那么割就是唯一的,即(A,B),否则(A,V-A)和(V-B,B)都是最小割. (注意因为割的 ...

  4. ZOJ 2532 Internship 求隔边

    Internship Time Limit: 5 Seconds      Memory Limit: 32768 KB CIA headquarter collects data from acro ...

  5. ZOJ 2532 Internship(最大流找关键割边)

    Description CIA headquarter collects data from across the country through its classified network. Th ...

  6. ZOJ 2753 Min Cut (Destroy Trade Net)(无向图全局最小割)

    题目大意 给一个无向图,包含 N 个点和 M 条边,问最少删掉多少条边使得图分为不连通的两个部分,图中有重边 数据范围:2<=N<=500, 0<=M<=N*(N-1)/2 做 ...

  7. ZOJ 2676 Network Wars(最优比例最小割)

    Network Wars Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge Network of Bytelan ...

  8. zoj 3165 (最小割,最大点权独立集)

    胡伯涛的<最小割模型在信息学竞赛中的应用>写的真牛. 这道题是选择一些男孩和女孩参加party,邀请的男孩女孩之间不能有 8g,图就是个明显的二分图,就是选择一些点之间没有8g关系,就是二 ...

  9. ZOJ 2587 Unique Attack (最小割唯一性)

    题意 判断一个无向图的割是否唯一 思路 错误思路:一开始想的是判断割边是否都是关键割边,那既然割边两端点能连通S.T点的边是关键边,那么只要遇到有某个边两端点不连通S or T则这条边就不是关键割边( ...

随机推荐

  1. CentOS6 Install kafka

    https://www.cnblogs.com/caoguo/p/5958608.html

  2. 各种ORM框架对比(理论篇,欢迎来观摩,并且纠正部分错误,防止误区)

    各种ORM框架对比 目前框架有以下 PetaPoco Dapper.NET Massive Simple.Data Chain PetaPoco 轻量级,以前单文件,目前有维护形成项目级别,适合多个数 ...

  3. makefile的语法及写法(二)

     3 Makefile书写规则 -------------------------------------------------------------------------------- 规则包 ...

  4. c++ static const

    static 是c++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因.作用谈起,全面分析static 修饰符的实质. static 的两大作用: 一. ...

  5. linux下查看哪个进程占用内存多

    1.用top命令 1.top top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 可以直接使用top命令后,查看%MEM的内容.可以 ...

  6. hdu4183往返经过至多每一个点一次/最大流

    题意:从s到t,每一个点有f值,仅仅能从f值小的到大的.到T后回来.仅仅能从f值大的到 小的,求可行否. 往返,事实上就是俩条路过去(每一个点最多一次).所以想到流量为2,跑最大流.看是否满2,又要每 ...

  7. superCleanMaster

    https://github.com/eltld/superCleanMaster

  8. java 报错非法的前向引用

    今天在看<thinking in java>的时候,第四章提到了非法的前向引用,于是自己试了一下,书中的例子倒是一下就明白了,但是自己写的一个却怎么也不明白,于是上网问了一位前辈,终于明白 ...

  9. Python开发【第2节】【Python运算符】

    Python语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符 成员运算符 身份运算符 运算符优先级 1.算术运算符 假设变量a = 10,变量b = 21: ...

  10. hdu 2059 龟兔赛跑 (dp)

    /* 把起点和终点比作加油站,那总共同拥有n+2个加油站了, 每次都求出从第0个到第j个加油站(j<i)分别在加满油的情况下到第i个加油站的最短时间dp[i], 终于的dp[n+1]就是最优解了 ...