| ||||||||||
| 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