zoukankan      html  css  js  c++  java
  • poj 3498 (最大流,枚举汇点)

    题意:有n块浮冰,每块上有一定数量的企鹅,每块浮冰可以承受企鹅跳一定的次数后消失,给出企鹅跳的最大距离,求所有企鹅能跳到哪块浮冰上见面。

    建图:添加源点,汇点,源点与浮冰相连,容量为浮冰上企鹅的数量,浮冰之间可以相互连边,所以要拆点,拆完后点与拆点间连边,容量为浮冰能承受企鹅跳的次数,如果两块浮冰i,j间可以到达,加边i+n—>j,j+n—>i,容量无穷大。然后枚举所有浮冰与汇点相连求最大流。








    #include<stdio.h>
    #include<string.h>
    const int N=210;
    const int inf=0x3fffffff;
    int dis[N],gap[N],head[N],num,start,end,ans,n;
    struct edge
    {
    	int st,ed,flow,next;
    }e[N*N];
    struct node
    {
    	double x,y;
    	int cont,po;
    }P[210];
    void addedge(int x,int y,int w)
    {
    	e[num].st=x;e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++;
        e[num].st=y;e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++;
    }
    double Dis(int i,int j)
    {
    	return (P[i].x-P[j].x)*(P[i].x-P[j].x)+(P[i].y-P[j].y)*(P[i].y-P[j].y);
    }
    int dfs(int u,int minflow)
    {
    	if(u==end)return minflow;
    	int i,v,f,flow=0,min_dis=ans-1;
    	for(i=head[u];i!=-1;i=e[i].next)
    	{
    		if(e[i].flow>0)
    		{
    			v=e[i].ed;
    			if(dis[v]+1==dis[u])
    			{
    				f=dfs(v,e[i].flow>minflow-flow?minflow-flow:e[i].flow);
    				e[i].flow-=f;
    				e[i^1].flow+=f;
    				flow+=f;
    				if(flow==minflow)break;
    				if(dis[start]>=ans)return flow;
    			}
    			min_dis=min_dis>dis[v]?dis[v]:min_dis;
    		}
    	}
    	if(flow==0)
    	{
    		if(--gap[dis[u]]==0)
    			dis[start]=ans;
    		dis[u]=min_dis+1;
    		gap[dis[u]]++;
    	}
    	return flow;
    }
    int isap()
    {
    	int maxflow=0;
    	memset(dis,0,sizeof(dis));
    	memset(gap,0,sizeof(gap));
    	gap[0]=ans;
    	while(dis[start]<ans)
    		maxflow+=dfs(start,inf);
    	return maxflow;
    }
    int main()
    {
    	int i,j,sum,t,flag,k;
    	double D;
    	scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%d%lf",&n,&D);
    		flag=0;sum=0;
            start=n+n;end=n+n+1;ans=end+1;		
    		for(i=0;i<n;i++)
    		{
    			scanf("%lf%lf%d%d",&P[i].x,&P[i].y,&P[i].cont,&P[i].po);
    			sum+=P[i].cont;			
    		}
    		for(k=0;k<n;k++)
    		{
    			memset(head,-1,sizeof(head));num=0;
    			addedge(k,end,inf);			
    			for(i=0;i<n;i++)
    			{
    				addedge(i,i+n,P[i].po);
    				addedge(start,i,P[i].cont);
    				for(j=i+1;j<n;j++)
    				{
    					if(Dis(i,j)<=D*D)
    					{
    						addedge(i+n,j,inf);
    						addedge(j+n,i,inf);
    					}
    				}		
    			}
    			if(isap()==sum)
    			{
    				printf("%d ",k);
    				flag++;
    			}
    		}
    		if(flag==0)printf("-1
    ");
    		else printf("
    ");
    	}
    	return 0;
    }
    


  • 相关阅读:
    hdu 1175
    hdu 2197
    STL的学习
    数据结构之线性结构栈
    Linux下Fork与Exec使用
    散列技术之哈希
    检索之二分检索
    检索之顺序检索
    程序员该怎样放松?8个好网站推荐
    外部碎片和内部碎片的区别
  • 原文地址:https://www.cnblogs.com/bbsno1/p/3257995.html
Copyright © 2011-2022 走看看