【题目】http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2532
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
const int M=2005;
int inf=1e9;
struct node
{
int u,v,nxt;
int flow;
} edge[M*2];
int ei;
int head[M*2];
int n,m,l;
int ans[M];
int start,end;
int path[M];
int andedge[M];
bool vis1[110],vis2[110];
void addedge(int u,int v,int f)
{
edge[ei].u=u;
edge[ei].v=v;
edge[ei].flow=f;
edge[ei].nxt=head[u];
head[u]=ei++;
}
void init()
{
memset(head,-1,sizeof(head));
memset(ans,-1,sizeof(ans));
ei=0;
}
bool bfs(int start, int end)
{
int que[M], vis[M], hhead=0, tail=1;
memset(vis, 0, sizeof (vis));
que[0] = start;
vis[start] = true;
while (tail > hhead)
{
int u = que[hhead++];
for (int i=head[u]; i!=-1; i=edge[i].nxt)
{
int v = edge[i].v;
if (!vis[v] && edge[i].flow)
{
path[v] = i;
if (v == end)
return true;
que[tail++] = v;
vis[v] = true;
}
}
}
return false;
}
void eend(int start, int end)
{
int i, u, sum=inf;
for (u=end; u!=start; u=edge[i].u)
{
i = path[u];
sum = std::min(sum, edge[i].flow);
}
for (u=end; u!=start; u=edge[i].u)
{
i = path[u];
edge[i].flow -= sum;
edge[i^1].flow += sum;
}
memset(path,-1,sizeof(path));
}
void EK(int start, int end)
{
while (bfs(start, end))
eend(start, end);
}
void dfs(int u,bool *vist,int op)
{
vist[u]=true;
for(int i=head[u];i!=-1;i=edge[i].nxt)
{
if(!vist[edge[i].v]&&edge[i^op].flow!=0)
{
dfs(edge[i].v,vist,op);
}
}
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&l)&&(n||m||l))
{
init();
for(int i=0; i<l; i++)
{
int u,v,f;
scanf("%d%d%d",&u,&v,&f);
addedge(u,v,f);
addedge(v,u,0);
}
start=n+m+1,end=0;
for(int i=1; i<=n; i++)
{
addedge(start,i,inf);
addedge(i,start,0);
}
//end 的边在scanf里就已经给出了,不用add了
EK(start,end);
memset(vis1,false,sizeof(vis1));
memset(vis2,false,sizeof(vis2));
dfs(start,vis1,0);//从源点向汇点搜索,标记还有剩余流的点
dfs(end,vis2,1);//从汇点到源点搜索,标记还有剩余流的点
int num=0;
for(int i=0;i<l;i++)
{
if(edge[i<<1].flow==0&&vis1[edge[i<<1].u]&&vis2[edge[i<<1].v])
{
ans[num++]=i+1;//如果一条边的u与v都被标记,表明s->u,v->end,但是这条边是满流,所以提升这条边。
}
}
if(num)
{
for(int i=0;i<num;i++)
{
if(i)
{
printf(" ");
}
printf("%d",ans[i]);
}
}
printf("\n");
}
}