最小点割集求解方法:

1.有向图:把一个点拆成(i, i+N)2个点,之间容量为1。如果i, j 2个点在原图中联通,则将i+N,j相连,容量为无穷大。然后求最小割,可见被最小割割到的都是容量是1的边,(如果割到一条INF,说明没有最小点割集。)而且那些边必将连着i,i+N,于是i就是被割的点。

2.无向图:把一个点拆成(i, i+N)2个点,之间容量为1。如果i, j 2个点在原图中联通,则将i+N,j相连,容量为无穷大。则将j, i+N相连,容量为无穷大。以下如上。

最小点权割集求解方法:把一个点拆成(i, i+N)2个点,之间容量为点的权值 其余同上。

本题思路:枚举每一个顶点,除了S和T之外,然后求最大流,看看去掉这个顶点和没去掉有没有影响。(最大流变小),要从小到大枚举。

这道题因为不能割源点或者汇点 所以在拆源点和汇点的时候 将边的权值设置为INF 这样就能保证不会割到源点和汇点了。

还有就是没有答案的时候的特判   如果源点和汇点直接相连 那么无论如何都能从源点到达汇点

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<stack>
#include<queue>
#include<cmath>
#include<stack>
#include<list>
#include<map>
#include<set>
typedef long long ll;
using namespace std;
const int MAXN=405;//jiedian de zui da zhi
const int MAXM=800000;//bian de zui da zhi
const int INF=0x3f3f3f3f;
struct Node
{int from,to,next;int cap;
}edge[MAXM];
int tol;
int head[MAXN];
int dep[MAXN];
int gap[MAXN];
void init()  //remember write it in main function
{tol=0;memset(head,-1,sizeof(head));
}void addedge(int u,int v,int w)
{edge[tol].from=u;edge[tol].to=v;edge[tol].cap=w;edge[tol].next=head[u];head[u]=tol++;edge[tol].from=v;edge[tol].to=u;edge[tol].cap=0;//wuxiangtu  this place change to w;edge[tol].next=head[v];head[v]=tol++;
}
void BFS(int start,int end)
{memset(dep,-1,sizeof(dep));memset(gap,0,sizeof(gap));gap[0]=1;int que[MAXN];int front,rear;front=rear=0;dep[end]=0;que[rear++]=end;while(front!=rear){int u=que[front++];if(front==MAXN)front=0;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(dep[v]!=-1)continue;que[rear++]=v;if(rear==MAXN)rear=0;dep[v]=dep[u]+1;++gap[dep[v]];}}
}
int SAP(int start,int end,int n) //n shi jiedian de zui da ge shu ,including source and sink
{int res=0;BFS(start,end);int cur[MAXN];int S[MAXN];int top=0;memcpy(cur,head,sizeof(head));int u=start;int i;while(dep[start]<n){if(u==end){int temp=INF;int inser;for(i=0;i<top;i++)if(temp>edge[S[i]].cap){temp=edge[S[i]].cap;inser=i;}for(i=0;i<top;i++){edge[S[i]].cap-=temp;edge[S[i]^1].cap+=temp;}res+=temp;top=inser;u=edge[S[top]].from;}if(u!=end&&gap[dep[u]-1]==0)break;for(i=cur[u];i!=-1;i=edge[i].next)if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)break;if(i!=-1){cur[u]=i;S[top++]=i;u=edge[i].to;}else{int min=n;for(i=head[u];i!=-1;i=edge[i].next){if(edge[i].cap==0)continue;if(min>dep[edge[i].to]){min=dep[edge[i].to];cur[u]=i;}}--gap[dep[u]];dep[u]=min+1;++gap[dep[u]];if(u!=start)u=edge[S[--top]].from;}}return res;
}int res[MAXN];
//双向图
int source,sink;
int a[MAXN][MAXN];
int getmap(int n)
{init();int i,j;for(i=1;i<=n;i++){if(i==source||i==sink)addedge(i, i+n, INF);elseaddedge(i, i+n, 1);for(j=1;j<=n;j++){if(j>i){if (a[i][j]) {addedge(i+n, j, INF);addedge(j+n, i, INF);}}}}int tt=SAP(source, sink+n, 2*n);return tt;
}
int mapx[MAXN];
int mapy[MAXN];
int main()
{int i,j,k;int n;while(scanf("%d%d%d",&n,&source,&sink)!=EOF){init();for(i=1;i<=n;i++){if(i==source||i==sink)addedge(i, i+n, INF);elseaddedge(i, i+n, 1);for(j=1;j<=n;j++){scanf("%d",&k);a[i][j]=k;if(j>i){if (k) {addedge(i+n, j, INF);addedge(j+n, i, INF);}}}}if(a[source][sink]==1){printf("NO ANSWER!\n");continue;}//特判int tt=SAP(source, sink+n, 2*n);printf("%d\n",tt);int cnt=0;for(i=1;i<=n;i++)//delete i{if(i==source||i==sink)continue;for(j=1;j<=n;j++){mapx[j]=a[i][j];//将第i行记录下来mapy[j]=a[j][i];//将第i列记录下来a[i][j]=a[j][i]=0;//全部清零 表示i点与图完全断绝}int ss=getmap(n);if(ss<tt){res[cnt++]=i;tt--;}else //如果流没有改变 说明此点不是割点 恢复{for(j=1;j<=n;j++){a[i][j]=mapx[j];a[j][i]=mapy[j];}}if(tt==0)break;}for(i=0;i<cnt;i++){printf("%d%c",res[i],i==cnt-1?'\n':' ');}}return 0;}

poj 1815 最小点割集相关推荐

  1. [图论]---[网络流]---最小点割数/最小点割集

    最小点割数 给定一个无向图,源点S和汇点T,问最少删除几个结点能使S和T不连通. 使S和T不连通的算法我们知道有最小割,但是最小割是将边割掉,所以我们需要将求割点转化为求割边. 我们知道如果在原图去掉 ...

  2. hdu3491 最小点割集(无向图求最小点割集通用方法)

    无向图最小点割集,确定起点S,终点T.每个点都有自己的点权值vi,求最小点权和的割点集,使得S无法到达T. 解法:将每个点拆分为两个点v和v',之间的权值为vi(单向边),将原图中的每条边赋权值为IN ...

  3. Ural 1277 Cops and Thieves(最小点割集/最小割)

    题意:一个团伙去偷一个美术馆,警察决定在路上堵截.警察人数为k,不能在贼窝和美术馆驻扎,只能在图上其他点驻扎,而且驻扎有一个最小人数要求,问警察能否完成任务. 解法:又是最小点割集题目,每个点拆点即可 ...

  4. poj 1815 Friendship 最小割 拆点 输出字典序

    题目链接:http://poj.org/problem?id=1815 题意:A与B能通信当且仅当A知道B的电话号或者A知道C的电话号且C与B能通信.若A知道B的电话号,那么B也知道A的电话号. 然而 ...

  5. poj 2516(最小费用最大流)

    其实题意很明确,最小费用最大流, 但是我这2货就建图就太二了, 我把所有的情况都弄到一个图里面. 总的点数有5000个,加上这么多的边,果断TLE... 后面知道第k个的情况是独立的,所以可以分成K次 ...

  6. poj 2516 最小费用最大流

    最佳匹配的题,m个仓库供应k种商品给n个商家,m*n条运输代价互异,求满足商家需求下的最小运输费用 显然,如果某种商品的供货量比需求大,肯定是无法达到要求的,所以开始要判别是否可以得到最佳匹配 这个题 ...

  7. poj 2728(最小比率生成树)

    参考题解:http://www.cppblog.com/jh818012/articles/167743.html 题意:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条 ...

  8. poj 3469(最小割)

    有一些模块(modules)和一个双核处理器,一个模块可以在任意一个核上处理,每个核对应每个模块有个开销.现在有一些模块间需要数据交换,如果需要数据交换的模块在一个核上处理,则不需要额外开销,否则需要 ...

  9. poj 3084 最小割

    1 /* 2 题意:给出m个房间,给出房间的连接情况,样例中给出的是第i间房可以到达t号房,而且 3 是无法阻止的,因为控制器在第i间房的这边,而且两个房间可以有多扇门:问最少要关闭 4 多少个门锁才 ...

最新文章

  1. HarmonyOS shape 的使用
  2. 【MySQL】(万字解析)MySQL表的增删改查(进阶-上)
  3. dbc2000找不到服务器控制台,控制面板没有BDE Administrator(安装好DBC2000找不到)
  4. Socket连接的小知识,和一个疑难杂症
  5. 就差一点点-微妙的强制类型转换
  6. Android中fragment之间和Activity的传值、切换
  7. 安卓手机阅读器_乐应用|安卓手机本地阅读的不二之选
  8. java调用python,传参json字符串,含中文传参
  9. BZOJ 2226 [Spoj 5971] LCMSum 最大公约数之和 | 数论
  10. Python3实现两个Excel文件内容比对
  11. 设备发现协议SSDP实现
  12. Java实现的中间库
  13. Python 画星星图案
  14. 使用Kaiju无组装计算宏基因组数据物种注释相对丰度
  15. 【华人学者风采】陈积明 浙江大学
  16. 华为nova6计算机历史在哪可以看,写在华为nova6发布前:一文看出nova手机使用芯片的变迁历程...
  17. dau计算公式_如何预估一个产品的日活(DAU)?
  18. Android属性ems
  19. ISIS TLV Cyrus
  20. ABBYY FineReader Server 与杂乱无章的较量。我们的解决方案如何去除重复内容,让商业文档井井有条?

热门文章

  1. Stream流-分组操作
  2. VC/MFC 从WebBrower 中获取 HTML 和文本
  3. [服务计算] 简单 web 服务与客户端开发实战
  4. Could not find apk!终于解决了! 坐在我旁边的领导帮我弄的~~ 大家谢谢他吧~~
  5. vue3.0网易云音乐及入门小案例
  6. 全链路前端性能优化方案
  7. cve-2019-0708漏洞复现
  8. 广告图片自动轮播控件
  9. linux 的常用命令---------第十阶段(虚拟机三种网络模式)
  10. element-ui 级联选择器el-cascader踩坑