您的位置:首页 > 理论基础 > 计算机网络

网络流入门

2016-07-30 10:08 393 查看
poj1459
http://poj.org/problem?id=1459
电站由组成consumer,dispatcher,power station,问最大传输电流

题意故意弄得非常复杂,其实就是多源多汇点,那么只要设置一个s往所有的源连,把所有的汇连到一个t再dinic就行了。

值得注意的两点:1.init必须在所有的开头调用 2.这题的(1,2)20这种读入比较奇葩,只要先读入buf,然后sscanf("(%d,%d)%d")就可以了

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<string>
#include<cctype>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<ctime>
using namespace std;
#define For(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,k,n) for(int i=n;i>=k;i--)
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define NEG(a) memset(a,-1,sizeof(a));
#define FILL(a) memset(a,0x3f,sizeof(a));
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define print(b,a) cout<<b<<"="<<a<<endl;
#define printbin(b,a){int tmp=a;string s;do{s+=tmp%2+'0';tmp/=2;}while(tmp);reverse(s.begin(),s.end());cout<<"bin "<<b<<"="<<s<<endl;}
#define printarr(i,a,f,b) {For(i,f,b) printf("%d ",a[i]); printf("\n");}

#define MAXN 400000
struct Node
{
int from,to,next;
int cap;
}edge[MAXN];
int tol;

int dep[MAXN];//dep为点的层次
int head[MAXN];

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++;
//printf("u=%d v=%d w=%d\n",u,v,w);
}

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];
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 d[250][250];
int K,C,M;
void floyd()
{
For(k,1,K+C)
For(i,1,K+C)
For(j,1,K+C)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
// For(i,1,K+C) For(j,1,K+C) printf("d[%d][%d]=%d\n",i,j,d[i][j] );
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d%d",&K,&C,&M);
For(i,1,K+C)
For(j,1,K+C) {
scanf("%d",&d[i][j]);
if(d[i][j]==0) d[i][j]=INF;
}
floyd();
int l=1,r=9999999,ans=1;
while(l<=r)
{
int m=(l+r)/2;
//printf("m=%d\n",m);
init();
For(i,1,K) addedge(0,i,M);
For(i,K+1,K+C) addedge(i,K+C+1,1);
For(i,1,K)
For(j,K+1,K+C)
if(m>=d[i][j]) addedge(i,j,1);
int ret=dinic(0,K+C+1);
//printf("ret=%d\n",ret);
if(ret==C)
{
r=m-1;
ans=m;
}
else
{
l=m+1;
}
}
printf("%d\n",ans);
return 0;
}


View Code

poj2455

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