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