[luogu 3254] 圆桌问题 {dinic算法,网络流24题}

题目

https://www.luogu.org/problemnew/show/P3254


结题思路

试题库问题很像。//听所贪心也能过
【需要注意的是:因为跟试题库问题的建图有一些区别,所以在输出的时候还要k.】


代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std; 
const int inf=1e6; 
struct node{
    int y,w,next; 
}a[80001];
queue<int>que; 
int k,n,m,s,t,ans,len=1,last[40001],dis[40001]; 
void add(int x,int y,int w)
{
    a[++len]={y,w,last[x]}; last[x]=len; 
    a[++len]={x,0,last[y]}; last[y]=len; 
}
bool bfs()
{
    memset(dis,0,sizeof(dis)); 
    while (!que.empty()) que.pop(); 
    dis[s]=1; que.push(s); 
    while (!que.empty()){
        int u=que.front(); que.pop(); 
        for (int i=last[u];i;i=a[i].next)
        if (a[i].w&&!dis[a[i].y]){
            dis[a[i].y]=dis[u]+1; 
            if (a[i].y==t) return 1; 
            que.push(a[i].y); 
        }
    }
    return 0; 
}
int dinic(int xq,int maxf)
{
    if (xq==t||!maxf) return maxf; 
    int ret=0,f=0; 
    for (int i=last[xq];i;i=a[i].next)
    if (a[i].w&&dis[a[i].y]==dis[xq]+1)
    {
        ret+=(f=dinic(a[i].y,min(a[i].w,maxf-ret))); 
        a[i].w-=f; a[i^1].w+=f; 
        if (maxf==ret) break; 
    }
    return ret; 
}
int main()
{
    scanf("%d%d",&k,&n); 
    int g; s=k+n+1; t=s+1; 
    for (int i=1;i<=k;i++)  scanf("%d",&g),m+=g,add(s,i,g); 
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&g),add(k+i,t,g);    
        for (int j=1;j<=k;j++) add(j,k+i,1); 
    }
    while (bfs()) ans+=dinic(s,inf); 
    if (ans==m){
        printf("1\n"); 
        for (int i=1;i<=k;printf("\n"),i++)
        {
            for (int j=last[i];j;j=a[j].next)
            if (a[j].y<=k+n&&a[j].y>k&&!a[j].w) printf("%d ",a[j].y-k); 
        }
    } else printf("0\n"); 
}
阅读更多
版权声明:请大家斧正,如喜欢的话,为拙见点一个赞吧。 https://blog.csdn.net/qq_39897867/article/details/81592823
上一篇[luogu 2763]试题库问题 {dinic算法,网络流24题}
下一篇[poj 1958] Strange Towers of Hanoi{递推}
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭