UVA 1660 Cable TV Network 电视网络(无向图,点连通度,最大流)
2015-07-20 19:27
549 查看
题意:给一个无向图,求其点连通度?(注意输入问题)
思路:
如果只有1个点,那么输出“1”;
如果有0条边,那么输出“0”;
其他情况:用最大流解决。下面讲如何建图:
图的连通度问题是指:在图中删去部分元素(点或边),使得图中指定的两个点s和t不连通(即不存在从s到t的路径),求至少要删去几个元素。
图的连通度分为点连通度和边连通度:
(1)点连通度:只许删点,求至少要删掉几个点(当然,s和t不能删去,这里保证原图中至少有三个点);
(2)边连通度:只许删边,求至少要删掉几条边。
并且,有向图和无向图的点连通度求法不同,因此还要分开考虑。说明:最大流对应的是最小割。
【有向图】:这个其实就是最小割问题。以s为源点,t为汇点建立网络,原图中的每条边在网络中仍存在,容量为1。
【无向图】:需要拆点,每个点都拆成两个点v和v',并连1条有向边v->v',容量为1。点v承接原图中所有入边,点v'承接原图中所有出边。那么对于原图每条有向边就得建两条边了,容量无穷,且涉4个新顶点。
【混合图】无向边按无向图处理,有向边按有向图处理。
最后,源点S到汇点,跑一次最大流,就得到了答案。如果无指定ST,那么应该顶下1个S,再穷举其他点作为T。这个S应该如何定就不知道了,时间充裕就穷举S和T,不充裕就找个度最少的为S。
针对此题,随意定个0号点为源点也能过,当然穷举两点也能过。
AC代码(穷举S和T)
思路:
如果只有1个点,那么输出“1”;
如果有0条边,那么输出“0”;
其他情况:用最大流解决。下面讲如何建图:
图的连通度问题是指:在图中删去部分元素(点或边),使得图中指定的两个点s和t不连通(即不存在从s到t的路径),求至少要删去几个元素。
图的连通度分为点连通度和边连通度:
(1)点连通度:只许删点,求至少要删掉几个点(当然,s和t不能删去,这里保证原图中至少有三个点);
(2)边连通度:只许删边,求至少要删掉几条边。
并且,有向图和无向图的点连通度求法不同,因此还要分开考虑。说明:最大流对应的是最小割。
【有向图】:这个其实就是最小割问题。以s为源点,t为汇点建立网络,原图中的每条边在网络中仍存在,容量为1。
【无向图】:需要拆点,每个点都拆成两个点v和v',并连1条有向边v->v',容量为1。点v承接原图中所有入边,点v'承接原图中所有出边。那么对于原图每条有向边就得建两条边了,容量无穷,且涉4个新顶点。
【混合图】无向边按无向图处理,有向边按有向图处理。
最后,源点S到汇点,跑一次最大流,就得到了答案。如果无指定ST,那么应该顶下1个S,再穷举其他点作为T。这个S应该如何定就不知道了,时间充裕就穷举S和T,不充裕就找个度最少的为S。
针对此题,随意定个0号点为源点也能过,当然穷举两点也能过。
#include <bits/stdc++.h> #define LL long long #define pii pair<int,int> #define INF 0x7f7f7f7f using namespace std; const int N=110; int n, m, edge_cnt; vector<int> vect[N*2]; int path , flow ; struct node { int from, to, cap, flow; node(){}; node(int f,int t,int c,int fl):from(f),to(t),cap(c),flow(fl){}; }edge[50000], cpy[50000], old[50000]; void add_node(int from, int to, int cap, int flow) { edge[edge_cnt]=node(from,to,cap,flow); vect[from].push_back(edge_cnt++); } int BFS(int s,int e) { deque<int> que(1,s); flow[s]=INF; while(!que.empty()) { int x=que.front(); que.pop_front(); for(int i=0; i<vect[x].size(); i++) { node e=cpy[vect[x][i]]; if(!flow[e.to] && e.cap>e.flow ) { flow[e.to]=min(flow[e.from],e.cap-e.flow); path[e.to]=vect[x][i]; que.push_back(e.to); } } if(flow[e]) break; } return flow[e]; } int max_flow(int s,int e) { int ans_flow=0; while(true) { memset(path,0,sizeof(path)); memset(flow,0,sizeof(flow)); int tmp=BFS(s,e); if(!tmp) return ans_flow; ans_flow+=tmp; int ed=e; while(ed!=s) { int t=path[ed]; cpy[t].flow+=tmp; cpy[t^1].flow-=tmp; ed=cpy[t].from; } } } int cal() { int ans=INF; for(int s=0; s<n; s++) //枚举源点 { memcpy(old, edge, sizeof(edge)); for(int i=0; i<edge_cnt; i++) { if( old[i].from==s*2 && old[i].to==s*2+1 && old[i].cap>0 ) { old[i].cap=INF; break; } } for(int k=s+1; k<n; k++) //枚举汇点 { memcpy(cpy, old, sizeof(old)); for(int i=0; i<edge_cnt; i++) //所有边 { if( cpy[i].from==k*2 && cpy[i].to==k*2+1 &&cpy[i].cap>0 ) { cpy[i].cap=INF; break; } } ans=min(ans, max_flow(s*2,k*2+1)); } } return ans==INF?n:ans; } int main() { //freopen("input.txt", "r", stdin); int a, b; char c; while(cin>>n>>m) { edge_cnt=0; memset(edge,0,sizeof(edge)); for(int i=n*2; i>=0; i--) vect[i].clear(); for(int i=0; i<n; i++) //拆点 { add_node(i*2, i*2+1, 1, 0); add_node(i*2+1, i*2, 0, 0); } for(int i=0; i<m; i++) { while(c=getchar(), c!='(' ); scanf("%d%c%d%c",&a,&c,&b,&c); add_node(a*2+1, b*2, INF, 0 ); //每条无向边拆2条有向 add_node(b*2, a*2+1, 0, 0 ); add_node(b*2+1, a*2, INF, 0); add_node(a*2, b*2+1, 0, 0); } printf("%d\n",cal()); } return 0; }
AC代码(穷举S和T)
相关文章推荐
- Node学习HTTP模块(HTTP 服务器与客户端)
- 网络协议概述:物理层、连接层、网络层、传输层、应用层详解(转载)
- Mac 启用http-dav功能(WebDAV服务器)
- AngularJS 用 $http.jsonp 方法跨域请求数据错误的问题
- ZOJ 3792 - Romantic Value (网络流‘最小割)
- [BZOJ1834][ZJOI2010]network 网络扩容
- 用iperf测试网络丢包和延迟
- android 判断网络是否连接 通过NetworkInfo
- 浅谈网络语音技术
- ubuntu中tinyos的安装
- Http和Https下的cookie(cookie 无法写入浏览器)
- http://blog.sina.com.cn/s/blog_877e9c3c0101gpnz.html
- 计算机网络(自顶向下的方法)学习笔记 1.2 网络边缘
- Nginx重要结构request_t解析之http请求的获取
- 在Windows如何解决下Cocos2d-x示例代码TestCpp我找不到lib问题库文件
- HttpServletRequest对象方法的用法
- mvc中HttpPost理解
- Github 主页:https://github.com/RunningYoung
- C# Socket的TCP通讯
- windows能连网络,但是打不开网页,出现无法解析服务器的DNS