【未完】【网络流 】ZOJ 2532 Internship

【题目】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");

    }
}

猜你喜欢

转载自blog.csdn.net/qq_32259423/article/details/81416778
ZOJ
今日推荐