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

思路:

  如果只有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. ContextLoaderListener作用详解

    参考网址:http://blog.csdn.net/ysughw/article/details/8992322 ContextLoaderListener监听器的作用就是启动Web容器时,自动装配A ...

  2. Asp.Net修改上传文件大小限制(修改web.config)

    i. Configuration节点下 <system.webServer> <security> <requestFiltering> <!--单位为字节  ...

  3. 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

    // test14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  4. 2014 Multi-University Training Contest 6

    官方解题报告:http://blog.sina.com.cn/s/blog_a19ad7a10102uz2v.html Apple Tree http://acm.hdu.edu.cn/showpro ...

  5. 在线最优化求解(Online Optimization)之三:FOBOS

    在线最优化求解(Online Optimization)之三:FOBOS FOBOS (Forward-Backward Splitting)是由John Duchi和Yoram Singer提出的[ ...

  6. asp.net 获取客户机IP地址

    /// <summary> ///get client IP /// </summary> /// <returns></returns> public ...

  7. android Notification定义与应用

    首先要明白一个概念: Intent 与 PendingIntent 的区别: Intent:是意图,即告诉系统我要干什么,然后做Intent应该做的事,而intent是消息的内容 PendingInt ...

  8. hdu 2837 Calculation

    公式:a^b%p=a^(b%phi(p)+phi(p))%p   b>=phi(p) #include<iostream> #include<stdio.h> #incl ...

  9. 序列dp笔记√

    例题: http://www.cnblogs.com/gc812/p/5792181.html http://www.cnblogs.com/gc812/p/5792217.html

  10. EXCEL排序

    题目描述:     Excel可以对一组纪录按任意指定列排序.现请你编写程序实现类似功能.     对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始).随后在 N ...