poj 1815 Friendship 最小割输出最小方案

这题卡了好久啊,最小割模型很容易想,拆点就行。就像poj的Thieves一样

每个点 a拆成 a->a‘,容量为1。

其他相连的点 a‘->b ,容量为INF

源连接s‘,t连接汇

问题在于输出最小的割集

更好的方法我还不会,只能枚举。

这里基于贪心的思想,从小到大删边,

若删除i->i‘,会使得最小割变小,则输出i,并且i->i‘这条边不要恢复

若最小割不变,则恢复这条边,继续枚举。

一开始就是因为恢复了要割去的边,无限WA。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<string>
#define eps  1e-12
#define INF   0x7fffffff
#define maxn 22222
using namespace std;
int n,m;
int en;
int st,ed,s,t;	//源点和汇点
int dis[maxn] ;//dis[i],表示  到 原点  s 的 层数
int que[9999999];
bool delet[maxn];
struct edge
{
	int u,to,c,next;
};
edge e[999999];
edge save[999999];
int head[maxn];
void add(int a,int b,int c)
{
	e[en].to=b;
	e[en].c=c;
	e[en].next=head[a];
	head[a]=en++;

	e[en].to=a;
	e[en].c=0;
	e[en].next=head[b];
	head[b]=en++;
}
int bfs()
{
    memset(dis,-1,sizeof(dis));
    dis[st]=0;
    int front=0,rear=0;
    que[rear++]=st;
    while(front<rear)
    {
        int j=que[front++];
        for(int k=head[j];k!=-1;k=e[k].next)
        {
            int i=e[k].to;
			if(dis[i]==-1&&e[k].c)
            {
                dis[i] = dis[j]+ 1 ;
                que[rear++]=i;
                if(i==ed) return true;
            }
        }
    }
    return false;
}
int dfs(int x,int mx)
{
    int i,a;
    if(x==ed) return mx ;
    int ret=0;
    for(int k=head[x];k!=-1&&ret<mx;k=e[k].next)
    {
        if(e[k].c&&dis[e[k].to]==dis[x]+1)
        {
            int dd=dfs(e[k].to,min(e[k].c,mx-ret));
            e[k].c-=dd;
            e[k^1].c+=dd;
            ret+=dd;
        }
    }
    if(!ret) dis[x]=-1;
    return ret;
}
bool del[maxn];
int a[205][205];
void init()
{
	st=0;     //源
    ed=n+n+1;     //汇
	for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    memset(del,0,sizeof(del));
}
void pr(int a,int b,int c)
{
    printf("%d --> %d =%d \n",a,b,c);
}
void build()
{
    en=0;
    memset(head,-1,sizeof(head));
    add(st,s+n,INF);
    for(int i=1;i<=n;i++)
    {
        if(!del[i])
        {
            add(i,i+n,1);
        }
        for(int j=1;j<=n;j++)
        {
            if(a[i][j])
            {
                add(i+n,j,INF);
            }
        }
    }
    add(t,ed,INF);
}
int dinic()
{
    int tmp=0;
    int maxflow=0;
    while(bfs())
    {
        while(tmp=dfs(st,INF)) maxflow+=tmp;
    }
    return maxflow;
}
int main()
{
    while(scanf("%d%d%d",&n,&s,&t)!=EOF)
    {
        init();
        build();
        if(a[s][t]) {puts("NO ANSWER!");continue;}
        int ans=dinic();
        printf("%d\n",ans);
        for(int i=1;i<=n;i++)
        {
            if(i==s||i==t) continue;
            del[i]=1;
            build();
            int tmp=dinic();
            if(tmp<ans)
            {
                if(ans-1) printf("%d ",i);
                else printf("%d",i);
                ans--;
            }
            else del[i]=0;
            if(ans==0) break;
        }
        puts("");
    }
}
/*
3 1 3
1 1 0
1 1 1
0 1 1

10 2 1
0 0 1 1 1 0 1 1 1 0
0 0 1 1 0 0 0 1 0 1
1 1 0 1 0 1 0 1 0 1
1 1 1 0 0 0 1 0 0 1
1 0 0 0 0 0 1 0 1 0
0 0 1 0 0 0 0 0 0 1
1 0 0 1 1 0 0 1 0 1
1 1 1 0 0 0 1 0 0 1
1 0 0 0 1 0 0 0 0 1
0 1 1 1 0 1 1 1 1 0

10 10 1
0 1 1 1 1 0 1 1 0 0
1 0 0 0 0 1 1 1 1 1
1 0 0 1 1 1 1 1 1 1
1 0 1 0 1 1 0 1 1 0
1 0 1 1 0 0 1 1 1 1
0 1 1 1 0 0 1 0 0 1
1 1 1 0 1 1 0 1 1 0
1 1 1 1 1 0 1 0 0 0
0 1 1 1 1 0 1 0 0 1
0 1 1 0 1 1 0 0 1 0
*/

poj 1815 Friendship 最小割输出最小方案

时间: 2024-12-23 02:13:26

poj 1815 Friendship 最小割输出最小方案的相关文章

POJ 1815 Friendship(最小割)

http://poj.org/problem?id=1815 Friendship Time Limit: 2000MS   Memory Limit: 20000K Total Submissions: 9026   Accepted: 2534 Description In modern society, each person has his own friends. Since all the people are very busy, they communicate with eac

Poj 1815 Friendship 枚举+求最小割

给以一个图和两个点S,T,问你拿掉最少多少个点可以使得S和T不连通.输出点数并且输出拿掉的是哪些点,如果有多种方法就输出字典序最小的那个. 这就是一个求最小点割集的问题.无向(有向)图G中,给定源点s和终点t,至少要删去多少个点(具体一点,删哪些点),使得s和t不连通.这个问题就是点连通度,也叫最小点割集. 解法其实理解起来不难,只要把图中的每一个点v拆成v',v''两个点,并建立<v',v''>权为1,这样就把最小点割集转化成求最小割的问题. 对于原图的转化也很简单,对于原来的每条边,转化成

poj 1815 Friendship (最小割+拆点+枚举)

题意: 就在一个给定的无向图中至少应该去掉几个顶点才能使得s和t不联通. 算法: 如果s和t直接相连输出no answer. 把每个点拆成两个点v和v'',这两个点之间连一条权值为1的边(残余容量) v和v''分别是一个流进的点,一个流出的点. 根据求最小割的性质,权值小的边是可能被选择的(断开的). 添加源点st=0和汇点en=2*n+1,源点与s连权值为inf的边,t''与汇点连权值为inf的边. s与s'',t与t''连权值为inf的边,这样保证自己和自己是不会失去联系的. 如果i和j有边

POJ 1815 Friendship(最小割)

POJ 1815 Friendship 链接:http://poj.org/problem?id=1815 题目:在现代社会,每个人都有自己的朋友.由于每个人都很忙,他们只通过电话联系.你可以假定A 可以和B 保持联系,当且仅当: (1) A 知道B 的电话号码,或 (2) A 知道C 的号码,而C 能联系上B. 如果A 知道B 的电话号码,则B 也知道A 的电话号码.有时,有人可能会碰到比较糟糕的事情,导致他与其他人失去联系.例如,他可能会丢失了电话簿,或者换了电话号码. 在本题中,告知N 个

bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)

2229: [Zjoi2011]最小割 题目:传送门 题解: 一道非常好的题目啊!!! 蒟蒻的想法:暴力枚举点对跑最小割记录...绝对爆炸啊.... 开始怀疑是不是题目骗人...难道根本不用网络流???一看路牌....分治最小割?最小割树? 然后开始各种%论文... 简单来说吧,根据各种本蒟蒻不会证明的理论,那么:所有最小割都不是完全独立的,总共有n-1种(也就是树上的n-1条边)最小割 恰好和树的定义一样啊! 那么用一个solve递归函数来解决,一开始任意找两个点作为st和ed来最小割,然后分

ZOJ 3792 Romantic Value 最小割(最小费用下最小边数)

求最小割及最小花费 把边权c = c*10000+1 然后跑一个最小割,则flow / 10000就是费用 flow%10000就是边数. 且是边数最少的情况.. #include<stdio.h> #include<string.h> #include<iostream> #include<math.h> #include<algorithm> #include<queue> #include<vector> using

POJ 1815 Friendship(最小割+字典序输出割点)

http://poj.org/problem?id=1815 题意: 在现代社会,每个人都有自己的朋友.由于每个人都很忙,他们只通过电话联系.你可以假定A可以和B保持联系,当且仅当:①A知道B的电话号码:②A知道C的电话号码,而C能联系上B.如果A知道B的电话号码,则B也知道A的电话号码. 思路:这题是要我们删点,既然是删点,那么就要拆点,容量就是1. 接下来凡是能联系的,就连边,容量为INF,因为我们不是要删除这些边.跑遍最大流就能算出至少要删除多少个点. 这道题的关键是要字典序顺序输出最小割

poj 1815 Friendship 字典序最小+最小割

题目链接:http://poj.org/problem?id=1815 In modern society, each person has his own friends. Since all the people are very busy, they communicate with each other only by phone. You can assume that people A can keep in touch with people B, only if 1. A kno

POJ 2125 --Destroying The Graph【最小割解决 &quot;最小点权覆盖问题&quot; &amp;&amp; 输出解(割边集) &amp;&amp; 各种不懂】

Destroying The Graph Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7597   Accepted: 2434   Special Judge Description Alice and Bob play the following game. First, Alice draws some directed graph with N vertices and M arcs. After that B