当前位置:编程学习 > C/C++ >>

hdu 3081&hdu 3277 (最大流)

hdu 3081题意:n个女孩,n个男孩,每个女孩有自己喜欢的男孩,她也会喜欢自己朋友喜欢的男孩,朋友间的关系是可以传递的。每个女孩每轮游戏要找一个喜欢的男孩过家家。问游戏最多能玩多少轮。
hdu 3277:跟3081题目意思大概一样,就是加了一个每个女孩可以选k个自己不喜欢的男孩。
hdu 3081:思路:图是二分图,如果把每个女孩跟喜欢的男孩连边,建设能玩D轮游戏,就是该图的最大流是D*n了,所以加上源点汇点,再二分找出最大的游戏论数。
hdu 3277:在一题上把女孩拆成两个点,拆出来的点连接不喜欢的男孩,在二分建图时不能太复杂,不然得TLE。
 
 
 
 
hdu 3081:
 
#include<stdio.h>  
#include<string.h>  
const int N=300;  
const int inf=0x3fffffff;  
int head[N],num,gap[N],dis[N],first[N],tot,f[N],start,end,ans,n;  
bool map[110][110];  
struct edge  
{  
    int st,ed,flow,next;  
}e[N*10000];  
struct node  
{  
    int ed,next;  
}E[N*N];  
int find(int a)  
{  
    if(a!=f[a])  
        f[a]=find(f[a]);  
    return f[a];  
}  
void addedge(int x,int y,int w)  
{  
    e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++;  
    e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++;  
}  
void Addedge(int x,int y)  
{  
    E[tot].ed=y;E[tot].next=first[x];first[x]=tot++;  
}  
int dfs(int u,int minflow)    
{    
    if(u==end)return minflow;    
    int i,v,f,min_dis=ans-1,flow=0;    
    for(i=head[u];i!=-1;i=e[i].next)    
    {    
        v=e[i].ed;    
        if(e[i].flow<=0)continue;    
        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(gap,0,sizeof(gap));  
    memset(dis,0,sizeof(dis));  
    gap[0]=ans;  
    while(dis[start]<ans)  
        maxflow+=dfs(start,inf);  
    return maxflow;  
}  
bool judge(int D)  
{  
    memset(head,-1,sizeof(head));  
    num=0;  
    int i,j;  
    for(i=1;i<=n;i++)  
    {  
        addedge(start,i,D);  
        addedge(i+n,end,D);  
        for(j=1;j<=n;j++)  
        {  
            if(map[i][j])addedge(i,j+n,1);  
        }         
    }  
    if(isap()==n*D)  
        return true;  
    return false;  
}  
int main()  
{  
    int i,j,k,m,F,t,x,y,flag;  
    scanf("%d",&t);  
    while(t--)  
    {  
        scanf("%d%d%d",&n,&m,&F);  
        tot=0;start=0;end=n+n+1;ans=end+1;  
        memset(first,-1,sizeof(first));  
        memset(map,false,sizeof(map));  
        for(i=1;i<=n;i++)  
            f[i]=i;  
        for(i=0;i<m;i++)  
        {  
            scanf("%d%d",&x,&y);  
            Addedge(x,y);  
            map[x][y]=true;  
        }  
        while(F--)  
        {  
            scanf("%d%d",&x,&y);  
            if(find(x)!=find(y))  
                f[find(x)]=find(y);  
        }  
        for(i=1;i<=n;i++)  
        {  
            for(j=i+1;j<=n;j++)  
            {  
                if(find(i)!=find(j))continue;  
                for(k=first[i];k!=-1;k=E[k].next)  
                    map[j][E[k].ed]=true;  
                for(k=first[j];k!=-1;k=E[k].next)  
                    map[i][E[k].ed]=true;                      
            }  
        }  
        int L=0,R=n,mid;  
        flag=0;  
        while(L<=R)  
        {  
            mid=(L+R)>>1;  
            if(judge(mid))  
            {  
                flag=mid;  
                L=mid+1;  
            }  
            else R=mid-1;  
        }  
        printf("%d\n",flag);  
    }  
    return 0;  
}  

 

 
 
hdu 3277:
 
 
#include<stdio.h>  
#include<string.h>  
const int N=1000;  
const int inf=0x3fffffff;  
int head[N],num,gap[N],dis[N],first[N],tot,f[N],start,end,ans,n,K;  
bool map[300][300];  
struct edge  
{  
    int st,ed,flow,next;  
}e[N*1000];  
struct node  
{  
    int ed,next;  
}E[N*N];  
int find(int a)  
{  
    if(a!=f[a])  
        f[a]=find(f[a]);  
    return f[a];  
}  
void addedge(int x,int y,int w)  
{  
    e[num].ed=y;e[num].flow=w;e[num].next=head[x];head[x]=num++;  
    e[num].ed=x;e[num].flow=0;e[num].next=head[y];head[y]=num++;  
}  
void Addedge(int x,int y)  
{  
    E[tot].ed=y;E[tot].next=first[x];first[x]=tot++;  
}  
int dfs(int u,int minflow)    
{    
    if(u==end)return minflow;    
    int i,v,f,min_dis=ans-1,flow=0;    
    for(i=head[u];i!=-1;i=e[i].next)    
    {    
        v=e[i].ed;    
        if(e[i].flow<=0)continue;    
        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(gap,0,sizeof(gap));  
    memset(dis,0,sizeof(dis));  
    gap[0]=ans;  
    while(dis[start]<ans)  
        maxflow+=dfs(start,inf);  
    return maxflow;  
}  
bool judge(int D)  
{  
    memset(head,-1,sizeof(head));  
    num=0;  
    int i,j;  
    for(i=1;i<=n;i++)  
    {  
        addedge(start,i,D);  
        addedge(i+n,end,D);  
        addedge(i,i+2*n,K);  
        for(j=1;j<=n;j++)  
        {  
            if(map[i][j])  
                addedge(i,j+n,1);  
            else addedge(i+2*n,j+n,1);  
        }  
    }  
    if(isap()==n*D)  
        return true;  
    return false;  
}  
int main()  
{  
    int i,j,k,m,F,t,x,y,flag;  
    scanf("%d",&t);  
    while(t--)  
    {  
        scanf("%d%d%d%d",&n,&m,&K,&F);  
        tot=0;start=0;end=n+n+n+1;ans=end+1;  
        memset(first,-1,sizeof(first));  
        memset(map,false,sizeof(map));  
        for(i=1;i<=n;i++)  
            f[i]=i;  
        for(i=0;i<m;i++)  
        {  
            scanf("%d%d",&x,&y);  
            Addedge(x,y);  
            map[x][y]=true;  
        }  
        while(F--)  
        {  
            scanf("%d%d",&x,&y);  
            if(find(x)!=find(y))  
                f[find(x)]=find(y);  
        }  
        for(i=1;i<=n;i++)  
        {  
            for(j=i+1;j<=n;j++)  
            {  
                if(find(i)!=find(j))continue;  
                for(k=first[i];k!=-1;k=E[k].next)  
                    map[j][E[k].ed]=true;  
                for(k=first[j];k!=-1;k=E[k].next)  
                    map[i][E[k].ed]=true;                      
            }  
        }  
        int L=1,R=n,mid;  
        flag=0;  
        while(L<=R)  
        {  
            mid=(L+R)>>1;  
            if(judge(mid))  
            {  
                flag=mid;  
                L=mid+1;  
            }  
            else R=mid-1;  
        }  
        printf("%d\n",flag);  
    }  
    return 0;  
}  

 

 
补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,