Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

为什么ek 0ms,而dinic却会超时??

Posted by ljpadam at 2013-03-16 13:57:34 on Problem 3436
#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:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator