poj 2289 (二分+最大流)

3 2
John 0 1
Rose 1
Mary 1
5 4
ACM 1 2 3
ICPC 0 1
Asian 0 2 3
Regional 1 2
ShangHai 0 2
0 0



题意:Jamie有很多联系人,但是很不方便管理,他想把这些联系人分成组,已知这些联系人可以被分到哪个组中去,而且要求每个组的联系人上限最小,即有一整数k,使每个组的联系人数都不大于k,问这个k最小是多少?


二分枚举最小值K  , 建图 ,源点与n个人  连边 ,流量1 ;  n个人和组连边,流量1 , m个组合汇点t连边,流量K ; 求一遍最大流,等于n 则说明符合,K值有可能 ;


我的代码,,一直说数组越界,不理解 !


#include
#include
#include
#include
#include
#include
#include
#include
#include 
#include
#include
using namespace std ;
const int N=5000 ; 
const int M=200000 ;
const int inf=1 << 30 ;

struct node
{
	int u,v,c,next ;
}edge[M] ;
int top ,s,t;
int pre[N],gap[N],cur[N],dis[N],head[N] ;
char str[100] ;

void add(int u ,int v,int c)  
{  
    edge[top].u=u;  
    edge[top].v=v;  
    edge[top].c=c;  
    edge[top].next=head[u];  
    head[u]=top++;  
    edge[top].u=v;  
    edge[top].v=u;  
    edge[top].c=0;  
    edge[top].next=head[v];  
    head[v]=top++;  
}  
  
int sap(int s,int t,int nv)  
{  
    memset(dis,0,sizeof(dis));  
    memset(gap,0,sizeof(gap));  
    for(int i = 0 ; i < nv ; i++)   cur[i]=head[i];  
    int minflow=inf ,flow = 0 ,u,v;  
    pre[s]=u=s;  
    gap[s]=nv;  
    while(dis[s] 0 && dis[u] == dis[v]+1)  
                       {  
                               pre[v]=u;  
                               u=v;  
                               minflow = min(minflow,edge[j].c);  
                               if(v==t)  
                               {    
                                    for(u=pre[v];v!=s;v=u,u=pre[u])  
                                    {  
                                        edge[cur[u]].c -= minflow ;  
                                        edge[cur[u]^1].c += minflow ;  
                                    }  
                                    flow += minflow;  
                                    minflow = inf ;  
                               }  
                             goto loop ;  
                       }  
                 }  
               int mindis=nv ;  
               for(int i = head[u] ; i!=-1 ; i=edge[i].next)  
               {  
                    v=edge[i].v;  
                    if(edge[i].c>0 && dis[v] < mindis)  
                    {  
                             cur[u]=i;  
                             mindis=dis[v];  
                    }  
               }  
               if(--gap[ dis[u] ]==0) break;  
               gap[ dis[u]=mindis+1 ]++;  
               u=pre[u];  
    }    
     return flow;  
}  


int main()
{
	
	int n,m ,x;
	while(~scanf("%d%d",&n,&m))
	{
	      if(n+m ==0) break ;
	      top=2;
		  memset(head,-1,sizeof(head)) ;
		   s = 0 , t = n+m+1 ;
		  for(int i = 1 ; i <= n ; i++){
		  	
		  	   scanf("%s",str) ;
		  	   add(s,i,1) ;
		  	   while(1)
		  	   {
		  	   	    scanf("%d",&x) ;
		  	        add(i,n+x+1,1) ;
					  if(getchar()=='\n') break ; 
		       }
		  } 
	     for(int i = 1 ; i <= m ; i++)
		    add(n+i,t,1)  ;
			 
		int l=1,r=n,mid ;	 
	      while(l


AC代码 ! 


#include
using namespace std;
#define MIN(a,b) (a0)
			{
				level[v]=level[now]+1;
				visit[v]=true;
				que[tail++]=v;
			}
		}
	}
	return false;
}
int dinic(int now,int sum)
{
	if(now==n+1+m)
		return sum;
	int os=sum;
	for(int i=edgehead[now];i&∑>0;i=edge[i].next)
	{
		int v=edge[i].v;
		if(level[v]==level[now]+1&&edge[i].w>0)
		{
			int tmp=dinic(v,MIN(edge[i].w,sum));
			edge[i].w-=tmp;
			edge[edge[i].re].w+=tmp;
			sum-=tmp;
		}
	}
	return os-sum;
}
bool make(int val)
{
	memset(edge,0,sizeof(edge));
	memset(edgehead,0,sizeof(edgehead));
	k=1;
	for(int i=1;i<=n;i++)
	{
		addedge(0,i,1);
		for(int j=1;match[i][j]!=-1;j++)
		{
			addedge(i,match[i][j]+n+1,1);
		}
	}
	for(int i=1;i<=m;i++)
	{
		addedge(i+n,n+1+m,val);
	}
	int ans=0;
	while(bfs())
	{
		ans+=dinic(0,inf);
	}
	if(ans==n)
	{
		return true;
	}
	else
	{
		return false;
	}
}
int main()
{
	//freopen("C:\\Users\\wuyanyisb\\Desktop\\1.txt","r",stdin);
	while(scanf("%d%d",&n,&m),n!=0||m!=0)
	{
		memset(match,0,sizeof(match));
		for(int i=1;i<=n;i++)
		{
			scanf("%s",name);
			char ch;
			int to;
			ch=getchar();
			int j=1;
			while(ch!='\n')
			{
				scanf("%d",&match[i][j]);
				ch=getchar();
				j++;
			}
			match[i][j]=-1;
		}
		int s=0,t=n+1;
		while(s




你可能感兴趣的:(网络流)