您的位置:首页 > 其它

poj 1459 Power Network 最大流,模板题

2014-01-08 19:28 387 查看
终于开始网络流了。

这道题可以设一个超级源点指向所有普通源点,一个超级汇点被所有汇点指向,然后计算最大流就是答案要求的最大电力。

读入太麻烦了可以用cin。不过…其实用输入外挂的话又快又省事。

EK算法很好懂。

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<iterator>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
//#define ll __int64
#define ll long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
int n,m,np,nc;
int p[200],flow[200][200],a[200],cap[200][200];
int s,t;    //超级源点和超级汇点
inline int ReadInt()
{
    char ch = getchar();
    int data = 0;
    while (ch < '0' || ch > '9')
    {
        ch = getchar();
    }
    do
    {
        data = data*10 + ch-'0';
        ch = getchar();
    }while (ch >= '0' && ch <= '9');
        return data;
}

int ek()
{
    queue<int> q;
    memset(flow,0,sizeof(flow));
    int f=0;
    for(;;)
    {
        memset(a,0,sizeof(a));
        a[s]=INF;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int v=0;v<=n+1;v++)
            {
                if(!a[v]&&cap[u][v]>flow[u][v])
                {
                    p[v]=u;
                    q.push(v);
                    a[v]=min(a[u],cap[u][v]-flow[u][v]);
                }
            }
        }
        if(a[t]==0) break;
        for(int u=t;u!=s;u=p[u])
        {
            flow[p[u]][u]+=a[t];
            flow[u][p[u]]-=a[t];
        }
        f+=a[t];
    }
    return f;
}
int main()
{
    int x,y,z;
    char e;
    while(~scanf("%d%d%d%d",&n,&np,&nc,&m))
    {
        memset(cap,0,sizeof(cap));
        t=s=n;t++;
        for(int i=1;i<=m;i++)
        {
            x=ReadInt();
            y=ReadInt();
            z=ReadInt();;
            cap[x][y]=z;
        }
        for(int i=1;i<=np;i++)
        {
            x=ReadInt();
            y=ReadInt();
            cap[s][x]=y;        //超级源点连向所有普通源点
        }
        for(int i=1;i<=nc;i++)
        {
            cin>>e>>x>>e>>y;    //所有普通汇点连向超级汇点
            cap[x][t]=y;
        }
        printf("%d\n",ek());
    }
    return 0;
}


-----------------------------------------------------------------------------------------------------------------------------------------

新加了dinic模板,解法一样,不过dinic快很多

/*迭代,快很多,125ms,*/

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

#define MAXN 105
#define INF 0x7FFFFFFF

struct edge
{
	int to,c,next;
};
edge e[999999];
int que[MAXN*100];
int dis[MAXN];
int pre[MAXN];
int head[MAXN],head2[MAXN];
int st,ed;
int maxflow;
int en;
int n,m;
inline int ReadInt()
{
    char ch = getchar();
    int data = 0;
    while (ch < '0' || ch > '9')
    {
        ch = getchar();
    }
    do
    {
        data = data*10 + ch-'0';
        ch = getchar();
    }while (ch >= '0' && ch <= '9');
        return data;
}
void add(int a,int b,int c)
{
	e[en].to=b;
	e[en].c=c;
	e[en].next=head[a];
	head[a]=en++;
	e[en].to=a;
	e[en].c=0;
	e[en].next=head[b];
	head[b]=en++;
}
bool bfs()
{
	memset(dis,-1,sizeof(dis));
	que[0]=st,dis[st]=1;
	int t=1,f=0;
	while(f<t)
	{
		int j=que[f++];
		for(int k=head[j];k!=-1;k=e[k].next)
		{
			int i=e[k].to;
			if(dis[i]==-1&&e[k].c)
			{
				que[t++]=i;
				dis[i]=dis[j]+1;
				if(i==ed) return true;
			}
		}
	}
	return false;
}
int update()
{
	int p,flow=INF;
    for (int i=pre[ed];i!=-1;i=pre[i])
		if(e[head2[i]].c<flow) p=i,flow=e[head2[i]].c;
    for (int i=pre[ed];i!=-1;i=pre[i])
		e[head2[i]].c-=flow,e[head2[i]^1].c+=flow;
    maxflow+=flow;
    return p;
}
void dfs()
{
	memset(pre,-1,sizeof(pre));
	memcpy(head2,head,sizeof(head2));
    for(int i=st,j;i!=-1;)
    {
        int flag=false;
        for(int k=head[i];k!=-1;k=e[k].next)
          if(e[k].c && (dis[j=e[k].to]==dis[i]+1) )
          {
                pre[j]=i;
				head2[i]=k;
				i=j;
				flag=true;
                if(i==ed)
					i=update();
                if(flag)
					break;
          }
        if (!flag) dis[i]=-1,i=pre[i];
    }
}
int dinic()
{
	st=n+1,ed=n+2;
	maxflow=0;
	while(bfs())
		dfs();
	return maxflow;
}
void init()
{
	int a,b,c;
	en=0;
	st=n+1;
    ed=n+2;
	memset(head,-1,sizeof(head));
}
int main()
{
    int np,nc,x,y,z;
    while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
    {
        init();
        for(int i=1;i<=m;i++)
        {
            x=ReadInt();
            y=ReadInt();
            z=ReadInt();
            x++;y++;            //由于dinic下标在1-n,所以输入+1
            add(x,y,z);
        }
        for(int i=1;i<=np;i++)
        {
            x=ReadInt();
            y=ReadInt();
            x++;
            add(st,x,y);
        }
        for(int i=1;i<=nc;i++)
        {
            x=ReadInt();
            y=ReadInt();
            x++;
            add(x,ed,y);
        }
        printf("%d\n",dinic());
    }

}




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: