Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
求好心人叉挂。。。。//每个点拆为i,i+n,连一条边,容量为1,费用为0 //若原图u到v有一条边,则新图里面u+n到v连一条边,容量为inf,费用为1 //求最小费用最大流,要求每次的增广路费用小于等于k //最后得出的流量即为答案 //求好心人叉挂。。。 #include <stdio.h> #include <cstdlib> #include <cstring> #include <deque> using namespace std; const int inf=10000000; struct data { int w; int next; }; int n,m,t; int cap[200][200],pay[200][200];//cap[][]容量,pay费用 int p[200];//记录增广路径 int d[300]; int f; deque<data> q; int s;//源点s=1+n,汇点为n bool vis[300]; int get()//找增广路 { for(int i=1;i<=2*n;i++) d[i]=inf; d[s]=0; memset(vis,false,sizeof(vis)); vis[s]=true; q.clear(); data np={d[s],s}; q.push_front(np); while(!q.empty()) { int k=q.front().next; q.pop_front(); for(int i=1;i<=2*n;i++) if(k!=i&&cap[k][i]>0&&d[k]+pay[k][i]<d[i]) { d[i]=d[k]+pay[k][i]; np.next=i; np.w=d[i]; p[i]=k; if(!vis[i]) { vis[i]=true; if(q.empty()||q.front().w>np.w) {q.push_front(np);} else q.push_back(np); } } } return d[n]; } int main() { while(scanf("%d%d%d",&n,&m,&t)==3) { if(n==0&&m==0&&t==0) break; memset(cap,0,sizeof(cap)); for(int i=1;i<=n;i++) cap[i][i+n]=1; memset(pay,0,sizeof(pay)); for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); cap[x+n][y]=inf; pay[x+n][y]=1; pay[y][x+n]=-1; } s=1+n; int f=0; while(1) { int fee=get(); if(fee>t) break; int tmp=inf; for(int u=n;u!=s;u=p[u]) if(cap[p[u]][u]<tmp) tmp=cap[p[u]][u]; f+=tmp; for(int u=n;u!=s;u=p[u]) { cap[p[u]][u]-=tmp; cap[u][p[u]]+=tmp; } } printf("%d\n",f); } } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator