题意:给一个无向图,求其点连通度?(注意输入问题)

思路:

  如果只有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=;
int n, m, edge_cnt;
vector<int> vect[N*];
int path[N], flow[N]; 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[], cpy[]; 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(,s);
flow[s]=INF; while(!que.empty())
{
int x=que.front();
que.pop_front();
for(int i=; 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=;
while(true)
{
memset(path,,sizeof(path));
memset(flow,,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^].flow-=tmp;
ed=cpy[t].from;
}
}
} int cal()
{
int ans=INF; for(int i=; i<edge_cnt; i++)
{
if( edge[i].from== && edge[i].to== && edge[i].cap> )
{
edge[i].cap=INF;
break;
}
}
for(int k=; k<n; k++) //枚举汇点
{
memcpy(cpy, edge, sizeof(edge));
for(int i=; i<edge_cnt; i++) //所有边
{
if( cpy[i].from==k* && cpy[i].to==k*+ &&cpy[i].cap> )
{
cpy[i].cap=INF;
break;
}
}
ans=min(ans, max_flow(,k*+));
}
return ans==INF?n:ans;
} int main()
{
freopen("input.txt", "r", stdin);
int a, b;
char c;
while(cin>>n>>m)
{
edge_cnt=;
memset(edge,,sizeof(edge));
for(int i=n*; i>=; i--) vect[i].clear(); for(int i=; i<n; i++) //拆点
{
add_node(i*, i*+, , );
add_node(i*+, i*, , );
} for(int i=; i<m; i++)
{
while(c=getchar(), c!='(' );
scanf("%d%c%d%c",&a,&c,&b,&c); add_node(a*+, b*, INF, ); //每条无向边拆2条有向
add_node(b*, a*+, , ); add_node(b*+, a*, INF, );
add_node(a*, b*+, , );
}
printf("%d\n",cal());
}
return ;
}

AC代码(任意源)

#include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=;
int n, m, edge_cnt;
vector<int> vect[N*];
int path[N], flow[N]; 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[], cpy[], old[]; 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(,s);
flow[s]=INF; while(!que.empty())
{
int x=que.front();
que.pop_front();
for(int i=; 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=;
while(true)
{
memset(path,,sizeof(path));
memset(flow,,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^].flow-=tmp;
ed=cpy[t].from;
}
}
} int cal()
{
int ans=INF;
for(int s=; s<n; s++) //枚举源点
{
memcpy(old, edge, sizeof(edge));
for(int i=; i<edge_cnt; i++)
{
if( old[i].from==s* && old[i].to==s*+ && old[i].cap> )
{
old[i].cap=INF;
break;
}
} for(int k=s+; k<n; k++) //枚举汇点
{
memcpy(cpy, old, sizeof(old));
for(int i=; i<edge_cnt; i++) //所有边
{
if( cpy[i].from==k* && cpy[i].to==k*+ &&cpy[i].cap> )
{
cpy[i].cap=INF;
break;
}
}
ans=min(ans, max_flow(s*,k*+));
}
} return ans==INF?n:ans;
} int main()
{
//freopen("input.txt", "r", stdin);
int a, b;
char c;
while(cin>>n>>m)
{
edge_cnt=;
memset(edge,,sizeof(edge));
for(int i=n*; i>=; i--) vect[i].clear(); for(int i=; i<n; i++) //拆点
{
add_node(i*, i*+, , );
add_node(i*+, i*, , );
} for(int i=; i<m; i++)
{
while(c=getchar(), c!='(' );
scanf("%d%c%d%c",&a,&c,&b,&c); add_node(a*+, b*, INF, ); //每条无向边拆2条有向
add_node(b*, a*+, , ); add_node(b*+, a*, INF, );
add_node(a*, b*+, , );
}
printf("%d\n",cal());
}
return ;
}

AC代码(穷举S和T)

UVA 1660 Cable TV Network 电视网络(无向图,点连通度,最大流)的更多相关文章

  1. UVA 1660 Cable TV Network

    题意: 求一个无向图的点连通度. 分析: 把一个点拆成一个入点和一个出点,之间连一条容量为1的有向边,表示能被用一次.最大流求最小割即可.套模板就好 代码; #include <iostream ...

  2. UVa 1660 Cable TV Network (最大流,最小割)

    题意:求一个无向图的点连通度. 析:把每个点拆成两个,然后中间连接一个容量为1的边,然后固定一个源点,枚举每个汇点,最小割. 代码如下: #pragma comment(linker, "/ ...

  3. Cable TV Network 顶点连通度 (最大流算法)

    Cable TV Network 题目抽象:给出含有n个点顶点的无向图,给出m条边.求定点联通度   K 算法:将每个顶点v拆成 v'   v''  ,v'-->v''的容量为1.       ...

  4. UVA1660 Cable TV Network (无向图的点连通度)

    题意:求一个无向图的点连通度. 把一个点拆成一个入点和一个出点,之间连一条容量为1的有向边,表示能被用一次.最大流求最小割即可. 一些细节的东西:1.源点固定,汇点要枚举一遍,因为最小割割断以后会形成 ...

  5. ZOJ 2182 Cable TV Network(无向图点割-最大流)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2182 题意:给出一个无向图,问最少删掉多少个顶点之后图变得不连通 ...

  6. UVA1660 电视网络 Cable TV Network

    题目地址:UVA1660 电视网络 Cable TV Network 枚举两个不直接连通的点 \(S\) 和 \(T\) ,求在剩余的 \(n-2\) 个节点中最少去掉多少个可以使 \(S\) 和 \ ...

  7. POJ 1966 Cable TV Network(顶点连通度的求解)

                               Cable TV Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissi ...

  8. POJ 1966 Cable TV Network

    Cable TV Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4702   Accepted: 2173 ...

  9. POJ 1966 Cable TV NETWORK(网络流-最小点割集)

                                    Cable TV NETWORK The interconnection of the relays in a cable TV net ...

随机推荐

  1. SqlServer 系统存储过程

    exec sp_databases; --查看数据库exec sp_tables; --查看表exec sp_columns Categories;--查看列exec sp_helpIndex Cat ...

  2. Matlab实现二进制矩阵转换为十进制

    一.问题描述 [1 1 1 0 1 0 1 1 0 1 0 0 1 1 0] 每两位3转换为一个十进制数,共5列,那么转换后是ceil(5/3)=2列. [7 1 6 1 1 2] 二.问题分析 1. ...

  3. Deep Learning and Shallow Learning

    Deep Learning and Shallow Learning 由于 Deep Learning 现在如火如荼的势头,在各种领域逐渐占据 state-of-the-art 的地位,上个学期在一门 ...

  4. Pycharm

    1.下载pycharm-community-3.0.2.exe 2.setting: keymap scheme:快捷键方案,可选择自带的:default:或者选择eclipse的快捷方案. ide ...

  5. 【hadoop2.6.0】MapReduce原理

    看了几篇博文,感觉还是云里雾里的. http://blog.csdn.net/opennaive/article/details/7514146 http://www.aboutyun.com/thr ...

  6. /bin/bash^M: bad interpreter: No such file or dire

    在执行shell脚本时提示这样的错误主要是由于shell脚本文件是dos格式,即每一行结尾以\r\n来标识,而unix格式的文件行尾则以\n来标识.  查看脚本文件是dos格式还是unix格式的几种办 ...

  7. Hibernate逍遥游记-第15章处理并发问题-001事务并发问题及隔离机制介绍

    1. 2.第一类丢失更新 3.脏读 4.虚读.幻读 5.不可重复读 6.第二类丢失更新 7.数据库的锁机制 8.数据库事务的隔离机制

  8. 在C#中怎么调用Resources文件中的图片

    譬如资源中有名为myPic的图片,在代码中可以这么使用: this.BackgroundImage = Properties.Resources.myPic; 如有疑问,继续追问.

  9. python流程控制语句 ifelse - 1

    考点:条件判断语句if-elif 代码: #! /usr/bin/python print ('\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n') p ...

  10. NET Remoting 示例

    .NET Remoting是.NET平台上允许存在于不同应用程序域中的对象相互知晓对方并进行通讯的基础设施.调用对象被称为客户端,而被调用对象则被称为服务器或者服务器对象.简而言之,它就是.NET平台 ...