POJ - 1459 Power Network

来源:互联网 发布:管家婆软件怎么注册 编辑:程序博客网 时间:2024/06/07 16:38

1.题面

http://poj.org/problem?id=1459

2.题意

水题

3.思路

看题意描述以为要拆点,但最后的求解出乎意料的简单

4.代码

/*****************************************************************    > File Name: cpp_acm.cpp    > Author: Uncle_Sugar    > Mail: uncle_sugar@qq.com    > Created Time: Sat 01 Oct 2016 22:52:30 CST*****************************************************************/# include <cstdio># include <cstring># include <cctype># include <cmath># include <cstdlib># include <climits># include <iostream># include <iomanip># include <set># include <map># include <vector># include <stack># include <queue># include <algorithm>using namespace std;# define rep(i,a,b) for (i=a;i<=b;i++)# define rrep(i,a,b) for (i=b;i>=a;i--)struct QuickIO{QuickIO(){const int SZ = 1<<20;setvbuf(stdin ,new char[SZ],_IOFBF,SZ);setvbuf(stdout,new char[SZ],_IOFBF,SZ);}//*From programcaicai*//}QIO;template<class T>void PrintArray(T* first,T* last,char delim=' '){    for (;first!=last;first++) cout << *first << (first+1==last?'\n':delim);}/*1.see the size of the input data before you select your algorithm 2.cin&cout is not recommended in ACM/ICPC3.pay attention to the size you defined, for instance the size of edge is double the size of vertex*/const int debug = 1;//# const int size  = 10 + ; const int INF = INT_MAX>>1;typedef long long ll;const int MAXN = 5000 + 10;const int MAXM = MAXN*MAXN;struct Edge{int to, f, nxt;}edge[MAXM];int tot = 0;int head[MAXN];void init(){tot = 0;memset(head, -1, sizeof(head));}void addedge(int from, int to, int f){edge[tot].to = to;edge[tot].f = f;edge[tot].nxt = head[from]; head[from] = tot++;edge[tot].to = from;edge[tot].f = 0;edge[tot].nxt = head[to]; head[to] = tot++;}int level[MAXN];bool bfs(int s, int t){static queue<int> que;while (!que.empty()) que.pop();memset(level, 0, sizeof(level));que.push(s); level[s] = 1;while (!que.empty()){int cur = que.front();que.pop();if (cur == t) return true;for (int e = head[cur]; ~e; e = edge[e].nxt){int to = edge[e].to, f = edge[e].f;if (!level[to] && f){level[to] = level[cur] + 1;que.push(to);}}}return false;}int dfs(int u, int t, int sup){if (u == t) return sup;int ret = 0;for (int e = head[u]; ~e; e = edge[e].nxt){int cur = edge[e].to, f = edge[e].f;if (level[cur] == level[u] + 1 && f){int mi = min(sup - ret, f);int tf = dfs(cur, t, mi);edge[e].f -= tf; edge[e^1].f += tf;ret += tf;if (ret == sup) return ret;}}return ret;}int Dinic(int s, int t){int ret = 0;while (bfs(s, t))  ret += dfs(s, t, INF);return ret;}int main(){/*std::ios::sync_with_stdio(false);cin.tie(0);*/int n, np, nc, m;while (~scanf("%d%d%d%d", &n, &np, &nc, &m)){init();while (m--){int a, b, c;while (getchar() != '(');scanf("%d,%d)%d", &a, &b, &c);++a;++b;addedge(a, b, c);}while (np--){int a, b;while (getchar() != '(');scanf("%d)%d", &a, &b);++a;addedge(0, a, b);}while (nc--){int a, b;while (getchar() != '(');scanf("%d)%d", &a, &b);++a;addedge(a, n+1, b);}ll ans = Dinic(0, n+1);printf("%lld\n", ans);}return 0;}

附上kuangbin的非递归dinic代码, 感谢kuangbin大神

地址是:点击打开链接

/*最大流模板dinic算法*/#include<stdio.h>#include<string.h>#include<algorithm>#include<iostream>using namespace std;const int INF=0x3f3f3f3f;const int MAXN=150;//点数的最大值const int MAXM=20500;//边数的最大值struct Node{    int from,to,next;    int cap;}edge[MAXM];int tol;int dep[MAXN];//dep为点的层次int head[MAXN];int n;void init(){    tol=0;    memset(head,-1,sizeof(head));}void addedge(int u,int v,int w)//第一条变下标必须为偶数{    edge[tol].from=u;    edge[tol].to=v;    edge[tol].cap=w;    edge[tol].next=head[u];    head[u]=tol++;    edge[tol].from=v;    edge[tol].to=u;    edge[tol].cap=0;    edge[tol].next=head[v];    head[v]=tol++;}int BFS(int start,int end){    int que[MAXN];    int front,rear;    front=rear=0;    memset(dep,-1,sizeof(dep));    que[rear++]=start;    dep[start]=0;    while(front!=rear)    {        int u=que[front++];        if(front==MAXN)front=0;        for(int i=head[u];i!=-1;i=edge[i].next)        {            int v=edge[i].to;            if(edge[i].cap>0&&dep[v]==-1)            {                dep[v]=dep[u]+1;                que[rear++]=v;                if(rear>=MAXN)rear=0;                if(v==end)return 1;            }        }    }    return 0;}int dinic(int start,int end){    int res=0;    int top;    int stack[MAXN];//stack为栈,存储当前增广路    int cur[MAXN];//存储当前点的后继    while(BFS(start,end))    {        memcpy(cur,head,sizeof(head));        int u=start;        top=0;        while(1)        {            if(u==end)            {                int min=INF;                int loc;                for(int i=0;i<top;i++)                  if(min>edge[stack[i]].cap)                  {                      min=edge[stack[i]].cap;                      loc=i;                  }                for(int i=0;i<top;i++)                {                    edge[stack[i]].cap-=min;                    edge[stack[i]^1].cap+=min;                }                res+=min;                top=loc;                u=edge[stack[top]].from;            }            for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)              if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to])                 break;            if(cur[u]!=-1)            {                stack[top++]=cur[u];                u=edge[cur[u]].to;            }            else            {                if(top==0)break;                dep[u]=-1;                u=edge[stack[--top]].from;            }        }    }    return res;}int main()//多源多汇点,在前面加个源点,后面加个汇点,转成单源单汇点{    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int start,end;    int np,nc,m;    int u,v,z;    while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)    {        init();        while(m--)        {            while(getchar()!='(');            scanf("%d,%d)%d",&u,&v,&z);            u++;v++;            addedge(u,v,z);        }        while(np--)        {            while(getchar()!='(');            scanf("%d)%d",&u,&z);            u++;            addedge(0,u,z);        }        while(nc--)        {            while(getchar()!='(');            scanf("%d)%d",&u,&z);            u++;            addedge(u,n+1,z);        }        start=0;        end=n+1;        int ans=dinic(start,end);        printf("%d\n",ans);    }    return 0;}


0 0