终于开始网络流了。
这道题可以设一个超级源点指向所有普通源点,一个超级汇点被所有汇点指向,然后计算最大流就是答案要求的最大电力。
读入太麻烦了可以用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()); } }