这道题的题意很难懂啊:有n个站点,nc个消费站点,np个 发电站,中间还有一些站点只传送不消耗也不发电。m条电缆。每条电缆上有最大的载电容量,求最大的消耗量。这是个多源点多汇点的题目,所以要构造一个虚拟的源点连接所有发电站,虚拟汇点连接所有消费站点。我都不知道什么好了,EK的话呢331ms.Dinic要1000多ms.有可能自己的代码太差了把。
EK代码:
#include<iostream>
#include<string.h>
using namespace std;
#define MAXN 205
#define INF 0x7fffffff
bool mark[MAXN];
int que[MAXN*10],map[MAXN][MAXN],pre[MAXN];
int n,mim,m;
__int64 total;
void Init()
{
memset(mark,0,sizeof(mark));
memset(que,0,sizeof(que));
for( int i=0; i<=n+1; i++)
pre[i]=-1;
}
bool Edmonds_Karp();
void Update();
int main()
{
int u,v,c;
int np,nc;
while( scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF){
memset(map,0,sizeof(map));
while( m--){
scanf(" (%d,%d)%d",&u,&v,&c);
map[u+1][v+1]=c;
}
while( np--){
scanf(" (%d)%d",&v,&c);
map[0][v+1]=c;
}
while( nc--){
scanf(" (%d)%d",&u,&c);
map[u+1][n+1]=c;
}
total=0;
while( Edmonds_Karp())
Update();
printf("%I64d\n",total);
}
return 0;
}
bool Edmonds_Karp()
{
int first,rear,u,v;
first=rear=0;
Init();
mark[0]=true;
que[rear++]=0;
while( first!=rear){
int u=que[first++];
for( v=1; v<=n+1; v++){
if( !mark[v]&&map[u][v]>0){
que[rear++]=v;
mark[v]=true;
pre[v]=u;
if( v==n+1) return true;
}
}
}
return false;
}
void Update()
{
mim=INF;
int u,v;
v=n+1;
while( v!=0&&v!=-1){
u=pre[v];
if( map[u][v]<mim)
mim=map[u][v];
v=pre[v];
}
total+=mim;
v=n+1;
while( v!=-1&&v!=0){
u=pre[v];
map[u][v]-=mim;
map[v][u]+=mim;
v=pre[v];
}
}
Dinic代码:
#include<iostream>
#include<string.h>
#define INF 0x7fffffff
#define maxn 205
using namespace std;
struct Edge
{
int v,f,next;
} e[maxn*maxn];
int head[maxn],level[maxn],size;
int que[maxn],s,t;
void AddEdge(int a,int b,int c)
{
e[size].v=b;
e[size].f=c;
e[size].next=head[a];
head[a]=size++;
}
bool BFS()
{
int first,rear,i,u,v;
first=rear=0;
memset(level,0,sizeof(level));
que[rear++]=s;
level[s]=1;
while( first!=rear){
u=que[first++];
if( u==t) return true;
for( i=head[u]; i!=-1; i=e[i].next){
v=e[i].v;
if( !level[v]&&e[i].f>0){
level[v]=level[u]+1;
que[rear++]=v;
}
}
}
return false;
}
int DFS(int u,int mimf) //优化的地方,回溯的时候。
{
if( u==t) return mimf;
int i,ret,f,v;
ret=0;
for( i=head[u]; i!=-1; i=e[i].next){
v=e[i].v;
if( e[i].f>0&&level[v]==level[u]+1){
f=DFS(v,min(mimf-ret,e[i].f));
e[i].f-=f;
e[i^1].f+=f;
ret+=f;
if( ret==mimf) return ret;
}
}
return ret;
}
int main()
{
int n,nc,np,m,a,b,c;
while( scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF){
size=0;
s=0; t=n+1; //原点,汇点
memset(head,-1,sizeof(head));
memset(e,0,sizeof(e));
while( m--){
scanf(" (%d,%d)%d",&a,&b,&c);
a++; b++;
AddEdge(a,b,c);
AddEdge(b,a,0);
}
while( np--){
scanf(" (%d)%d",&b,&c);
b++;
AddEdge(0,b,c);
AddEdge(b,0,0);
}
while( nc--){
scanf(" (%d)%d",&a,&c);
a++;
AddEdge(a,t,c);
AddEdge(t,a,0);
}
int ret=0;
while( BFS()){
ret+=DFS(s,INF);
}
printf("%d\n",ret);
}
return 0;
}