poj1815+sap+枚举+最小割点集
来源:互联网 发布:唱歌声卡软件下载 编辑:程序博客网 时间:2024/05/21 11:10
建图:
1)每个点v变成网络N里的两个点v*和v**,并有一条弧<v*,v**>,容量为1
2)对于图中的每一条无向边<u,v>,在网络N有两条弧<u**,v*>,<v**,u*>,且容量为无穷大
3)另A**为源点,B*为汇点
求出最小割点集数目之后,枚举每一个点,并删除,如果网络N的最小割点数减少,则意味着该点为割点并保存
#include <map>#include <set>#include <queue>#include <stack>#include <math.h>#include <vector>#include <cstdio>#include <string>#include<string.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;#define INF 999999999;const int maxn=10000; //边的数量,应该比正常边的数量多两倍const int MAXN=10000;//节点数int cur[MAXN];//当前弧优化int pre[MAXN];//先祖int level[MAXN];//高度int gap[MAXN];//gap优化bool vis[MAXN][MAXN];struct EDGE {int to,cost,next;}edge[maxn];int head[maxn],cnt;bool deleted[maxn];inline void addedge(int a,int b,int c){edge[cnt].to=b;edge[cnt].cost=c;edge[cnt].next=head[a];head[a]=cnt++;edge[cnt].to=a;edge[cnt].cost=0;edge[cnt].next=head[b];head[b]=cnt++;}void build_graph(int n) //节点数(1->n),边数 {cnt=0;memset(head,-1,sizeof(head));for(int i=1;i<=n;i++)//只需要修改一下输入即可if(!deleted[i])addedge(i,i+n,1);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)if(!deleted[i]&&!deleted[j]&&i!=j&&vis[i][j])addedge(i+n,j,99999);}int sap(int tot,int s,int t) //无需改动{memset(pre,-1,sizeof(pre));memset(gap,0,sizeof(gap));memset(level,0,sizeof(level));gap[0]=tot;int u=s,ans=0,inf=INF;for(int i=0; i<tot; i++)//初始化当前弧为第一条弧 cur[i]=head[i];while(level[s]<tot){bool flag=0;for(int &i=cur[u];i!=-1;i=edge[i].next) //读取边,并更新当前弧{int v=edge[i].to;if(edge[i].cost>0&&level[u]==level[v]+1){flag=1;if(edge[i].cost<inf)inf=edge[i].cost;pre[v]=u;u=v;if(u==t){while(u!=s) //结束后u==s{u=pre[u];edge[cur[u]].cost-=inf;edge[cur[u]^1].cost+=inf;//异或是找与其配对的边}ans+=inf;inf=INF;}break;}}if(!flag){if(--gap[level[u]]==0)//gap优化break;int minn=tot;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(edge[i].cost>0&&level[v]<minn){minn=level[v];cur[u]=i;//更新当前弧,让其从度最小的线段开始}}level[u]=minn+1;gap[minn+1]++;if(u!=s)u=pre[u];}}return ans;}int main(){int n,s,t;while(~scanf("%d %d %d",&n,&s,&t)){memset(deleted,0,sizeof(deleted));build_graph(n);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&vis[i][j]);if(vis[s][t]){printf("NO ANSWER!\n");continue;}build_graph(n);int ans=sap(2*n,s+n,t);printf("%d\n",ans); //找出割点数量if(!ans) continue;for(int i=1;i<=n&&ans;i++){if(i==s||i==t)continue;deleted[i]=1;build_graph(n);int kk=sap(2*n,s+n,t);if(kk<ans) //如果该点为割点,则保存,总的数目也减1ans--;else //否则标志恢复deleted[i]=0;}for(int i=1;i<=n;i++)if(deleted[i])printf("%d ",i);printf("\n");}return 0;}
0 0
- poj1815+sap+枚举+最小割点集
- poj1815(最小割点集)
- POJ1815 Friendship 最小点割集
- poj1815
- POJ1815
- 【POJ1815】Friendship 网络流最小割
- POJ1815 Friendship(求最小割点 dinic)
- POJ1815 Friendship
- POJ1815 Friendship
- 网络流(最小割最大流(记录路径))【POJ1815】
- POJ 1815 SAP+枚举
- SAP RFC user 最小权限
- poj 1815 Friendship 【最小割点集】【枚举删点 + 求解最小字典序】
- poj--1815--Friendship(最小割点集)(枚举求最小字典序)
- LA3887 最小生成树 枚举最小边
- poj 1815(最小割+枚举)
- Kingdoms 枚举+最小生成树
- POJ 3469 构图最小割+链表SAP
- UVaOJ-11624-Fire! 解题报告
- ??html阻止事件冒泡
- PAT_B_字符串-06. IP地址转换(20)
- 七步从AngularJS菜鸟到专家(4和5):指令和表达式(1)
- 七步从AngularJS菜鸟到专家(6):服务(1)
- poj1815+sap+枚举+最小割点集
- 理解互斥量和信号量 .
- 七步从AngularJS菜鸟到专家(7):Routing(1)
- [python]去除列表中重复元素
- LeetCode-Max Points on a Line[AC源码]
- 目标跟踪的点跟踪技术(4)
- 隐藏office web app打印和在word中打开等功能
- java的多态
- zoj 1654 Place the Robots 二分图匹配