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 |
为什么ek 0ms,而dinic却会超时??#include <iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=120; const int INF=0x3f3f3f3f; int s[N][N];//记录图的邻接矩阵 int d[N];//记录图中各点的层次 int n,m; int p; int g[N][N]; int min(int a,int b) { return a<b?a:b; } bool bfs() { queue<int>Q; //memset(d,-1,sizeof(d));//此处初始化要特别注意,以上版本的初始化就存在很大问题 for(int i=1;i<N;i++) d[i]=-1;; //for(int i=1;i<N;i++) cout<<d[i]; //cout<<endl; d[0]=0;//如果处理不慎就很容易死循环 Q.push(0); while(!Q.empty()){ int v=Q.front();Q.pop(); for(int i=0;i<=2*n+1;i++){ if(d[i]==-1&&s[v][i]!=0){//此处应是s[v][i]!=0,而不是以上版本中的s[v][i]>0,因为dfs是可能会走错,这样可以对其进行修正。 d[i]=d[v]+1; Q.push(i); } } } return d[2*n]!=-1; } int dfs(int v,int cur_flow) { int dt=cur_flow; if(v==2*n+1)return cur_flow; for(int i=0;i<=2*n+1;i++){ if(s[v][i]>0&&d[v]+1==d[i]){ int flow=dfs(i,min(dt,s[v][i])); s[v][i]-=flow; s[i][v]+=flow; dt-=flow; } } return cur_flow-dt; } int dinic() { int cur_flow,ans=0; while(bfs()){//一次bfs可以找到几条增广路 while(cur_flow=dfs(0,INF)) ans+=cur_flow; } return ans; } int main() { int k=0; while(scanf("%d%d",&p,&n)!=EOF) { int q[N],x[N][20],d[N][20]; k++; memset(s,0,sizeof(s)); memset(q,0,sizeof(q)); memset(x,0,sizeof(x)); memset(d,0,sizeof(d)); for(int i=1;i<=n;i++) { scanf("%d",&q[i]); s[i][n+i]=q[i];//拆点 for(int j=1;j<=p;j++) scanf("%d",&x[i][j]); for(int j=1;j<=p;j++) scanf("%d",&d[i][j]); } for(int i=1;i<=n;i++) { int ok=1; for(int j=1;j<=p;j++)//和源点建边 { if(x[i][j]==1) { ok=0; break; } } if(ok) {s[0][i]=q[i];}//进入点为i,出发点位i+n ok=1; for(int j=1;j<=p;j++)//和汇点建边 { if(d[i][j]==0||d[i][j]==2) { ok=0; break; } } if(ok) {s[n+i][2*n+1]=q[i];} ok=1; for(int ii=1;ii<=n;ii++)//和其他点建边 { ok=1; if(ii==i) { ok=0; continue; } for(int j=1;j<=p;j++) { if((x[ii][j]+d[i][j])==1) { ok=0; break; } } if(ok) { s[n+i][ii]=q[i]; } } } memset(g,0,sizeof(g)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) g[i+n][j]=s[i+n][j]; int ans; ans=dinic(); int k=0; queue<int> a; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(g[i+n][j]) { if(g[i+n][j]>s[i+n][j]) { k++; a.push(i); a.push(j); a.push(g[i+n][j]-s[i+n][j]); } } } } printf("%d %d\n",ans,k); while(!a.empty()) { for(int i=1;i<=3;i++) { printf("%d ",a.front()); a.pop(); } printf("\n"); } } return 0; } Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator