POJ1815_Friendship
一个无向图,问你删除多少点后,可以隔断起点到终点的所有路径?输出字典序最小的删点方案。
求最小点割,先拆点,容量为1,普通边容量无穷,最大流即为应删点数。
需要求出字典序最小的方案,可以从小到大枚举所有的点,如果当前枚举的点是割点,那么进行标记,同时后面的枚举也不再经过这个点。
召唤代码君:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#define maxn 5555
#define maxm 555555
using namespace std; int to[maxm],next[maxm],c[maxm],belong[maxm],first[maxm],edge;
int d[maxn],tag[maxn],TAG=;
bool can[maxn],go[maxn];
int Q[maxn],bot,top;
int f[][];
int s,t,n,pos[maxn]; void _init()
{
edge=-;
for (int i=; i<=n+n; i++) first[i]=-,go[i]=false;
} void addedge(int U,int V)
{
edge++;
to[edge]=V,c[edge]=,next[edge]=first[U],first[U]=edge;
edge++;
to[edge]=U,c[edge]=,next[edge]=first[V],first[V]=edge;
} bool bfs()
{
Q[bot=top=]=t,tag[t]=++TAG,d[t]=,can[t]=false;
while (bot<=top)
{
int cur=Q[bot++];
for (int i=first[cur]; i!=-; i=next[i])
if (c[i^]> && tag[to[i]]!=TAG && !go[to[i]])
{
tag[to[i]]=TAG,d[to[i]]=d[cur]+;
can[to[i]]=false,Q[++top]=to[i];
if (to[i]==s) return true;
}
}
return false;
} int dfs(int cur,int num)
{
if (cur==t) return num;
int tmp=num,k;
for (int i=first[cur]; i!=-; i=next[i])
if (c[i]> && tag[to[i]]==TAG && d[to[i]]==d[cur]- && !can[to[i]])
{
k=dfs(to[i],min(num,c[i]));
if (k) num-=k,c[i]-=k,c[i^]+=k;
if (!num) break;
}
if (num) can[cur]=true;
return tmp-num;
} int maxflow()
{
int flow=;
while (bfs()) flow+=dfs(s,~0U>>);
return flow;
} int get(int x)
{
for (int i=first[x]; i!=-; i=next[i])
if (c[i]== && !(i&))
{
int tmp=to[i];
tmp-=x;
if (tmp<) tmp=-tmp;
if (tmp!=n) return get(to[i]);
tmp=min(x,to[i]);
return min(tmp,get(to[i]));
}
return ~0U>>;
} int main()
{
int tmp,mf;
vector<int> ans;
while (scanf("%d%d%d",&n,&s,&t)!=EOF)
{
_init();
for (int i=; i<=n; i++) addedge(i,i+n),pos[i]=edge;
for (int i=; i<=n; i++)
for (int j=; j<=n; j++)
{
scanf("%d",&tmp);
f[i][j]=f[j][i]=tmp;
if (i>=j) continue;
if (tmp) addedge(i+n,j),addedge(j+n,i);
}
if (s==t || f[s][t])
{
puts("NO ANSWER!");
continue;
}
s+=n;
ans.clear();
mf=maxflow();
printf("%d\n",mf);
if (mf==) continue;
for (int i=; i<=n && mf>; i++)
{
if (i==s-n || i==t) continue;
for (int j=; j<edge; j+=) c[j]+=c[j+],c[j+]=;
go[i]=true,go[i+n]=true;
tmp=maxflow();
if (tmp<mf) ans.push_back(i),mf--;
else go[i]=false,go[i+n]=false;
} sort(ans.begin(),ans.end());
printf("%d",ans[]);
for (unsigned i=; i<ans.size(); i++) printf(" %d",ans[i]);
printf("\n");
}
return ;
}
POJ1815_Friendship的更多相关文章
随机推荐
- 动态加载与插件系统的初步实现(四):解析JSON、扩展Fiddler
按文章结构,这部分应该给出WCFRest项目示例,我想WinForm示例足够详尽了,况且WCFRest还不需要使用插件AppDomain那一套,于是把最近写的Fiddler扩展搬上来吧. Fiddle ...
- MySQL5.7(二)数据库的基本操作
登录MySQL数据库 格式:mysql -u 用户名 -h 主机名或IP地址 -P 端口号 -p 密码
- 从零开始的Python学习Episode 19——面向对象(2)
面向对象之继承 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称 为基类或超类,新建的类称为派生类或子类. 子类会“”遗传”父类的属性,从而解决代码重用问 ...
- node jade模板数据库操作
/* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50519 Sourc ...
- [转载] Ubuntu 12.04下安装git,SSH及出现的Permission denied解决办法
如何安装ssh http://os.51cto.com/art/201109/291634.htm 仅需要阅读至成功开启ssh服务即可 http://www.linuxidc.com/Linux/20 ...
- fdisk命令详解
基础命令学习目录 原文链接:https://www.cnblogs.com/xiaofengkang/archive/2011/06/06/2073579.html fdisk -l 可以列出所有的分 ...
- Python基础系列讲解——TCP协议的socket编程
前言 我们知道TCP协议(Transmission Control Protocol, 传输控制协议)是一种面向连接的传输层通信协议,它能提供高可靠性通信,像HTTP/HTTPS等网络服务都采用TCP ...
- 利用Cocoapods创建基于SVN的私有库podspec
由于项目年后要进行组件化,考虑到公司内部实现的一些私有组件,不对外公开,而又想在不同项目中使用,该怎么办呢?由于cocoapods有了强大的功能,可以自己创建podspec,更可以设置私有的库.那么利 ...
- (第六周)课上Scrum站立会议演示
组名:连连看 组长:张政 组员:张金生.李权.武志远 时间:2016.10.13 20:20——20:40 会议内容: 已完成的内容: 1.选定编译语言,安装软件并配置环境,完成了游戏的基本模型. ...
- P2P通讯原理
1.简介 当今互联网到处存在着一些中间件(MIddleBoxes),如NAT和防火墙,导致两个(不在同一内网)中的客户端无法直接通信.这些问题即便是到了IPV6时代也会存在,因为即使不需要NAT,但还 ...