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

题意:求一个无向图的点连通度。

析:把每个点拆成两个,然后中间连接一个容量为1的边,然后固定一个源点,枚举每个汇点,最小割。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-5;
const int maxn = 100 + 10;
const int mod = 1e6;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
  return r >= 0 && r < n && c >= 0 && c < m;
}
struct Edge{
  int from, to, cap, flow;
};

struct Dinic{
  int m, s, t;
  vector<Edge> edges;
  vector<Edge> tmp;
  vector<int> G[maxn];
  bool vis[maxn];
  int d[maxn];
  int cur[maxn];

  void init(){
    edges.clear();
    for(int i = 0; i < maxn; ++i)  G[i].clear();
  }
  bool bfs(){
    memset(vis, 0, sizeof vis);
    queue<int> q;
    q.push(s);
    d[s] = 0;  vis[s] = true;
    while(!q.empty()){
      int x = q.front();  q.pop();
      for(int i = 0; i < G[x].size(); ++i){
        Edge &e = edges[G[x][i]];
        if(!vis[e.to] && e.cap > e.flow){
          vis[e.to] = 1;
          d[e.to] = d[x] + 1;
          q.push(e.to);
        }
      }
    }
    return vis[t];
  }

  int dfs(int x, int a){
    if(x == t || a == 0)  return a;
    int flow = 0, f;
    for(int& i = cur[x]; i < G[x].size(); ++i){
      Edge& e = edges[G[x][i]];
      if(d[x] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap-e.flow))) > 0){
        e.flow += f;
        edges[G[x][i]^1].flow -= f;
        flow += f;
        a -= f;
        if(!a)  break;
      }
    }
    return flow;
  }

  int maxflow(int s, int t){
    this->s = s;  this->t = t;
    int flow = 0;
    while(bfs()){
      memset(cur, 0, sizeof cur);
      flow += dfs(s, INF);
    }
    return flow;
  }

  void addEdge(int from, int to, int cap){
    edges.push_back(Edge{from, to, cap, 0});
    edges.push_back(Edge{to, from, 0, 0});
    m = edges.size();
    G[from].push_back(m-2);
    G[to].push_back(m-1);
  }
};
Dinic dinic;

int main(){
  while(scanf("%d %d", &n, &m) == 2){
    dinic.init();
    for(int i = 0; i < n; ++i)  dinic.addEdge(i, i+n, 1);
    for(int i = 0; i < m; ++i){
      int u, v;
      scanf(" (%d,%d)", &u, &v);
      dinic.addEdge(u+n, v, INF);
      dinic.addEdge(v+n, u, INF);
    }
    dinic.tmp = dinic.edges;
    int ans = INF;
    for(int i = 1; i < n; ++i){
      ans = min(ans, dinic.maxflow(n, i));
      dinic.edges = dinic.tmp;
    }
    printf("%d\n", ans == INF ? n : ans);
  }
  return 0;
}
时间: 2024-08-09 01:27:45

UVa 1660 Cable TV Network (最大流,最小割)的相关文章

UVA 1660 Cable TV Network 电视网络(无向图,点连通度,最大流)

题意:给一个无向图,求其点连通度?(注意输入问题) 思路: 如果只有1个点,那么输出“1”: 如果有0条边,那么输出“0”: 其他情况:用最大流解决.下面讲如何建图: 图的连通度问题是指:在图中删去部分元素(点或边),使得图中指定的两个点s和t不连通(即不存在从s到t的路径),求至少要删去几个元素. 图的连通度分为点连通度和边连通度: (1)点连通度:只许删点,求至少要删掉几个点(当然,s和t不能删去,这里保证原图中至少有三个点): (2)边连通度:只许删边,求至少要删掉几条边. 并且,有向图和

UVA 1660 Cable TV Network

题意: 求一个无向图的点连通度. 分析: 把一个点拆成一个入点和一个出点,之间连一条容量为1的有向边,表示能被用一次.最大流求最小割即可.套模板就好 代码; #include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <queue>using namespace std;const int maxn=110;#define INF 1<

POJ 1966 Cable TV Network 【经典最小割问题】

Description n个点的无向图,问最少删掉几个点,使得图不连通 n<=50 m也许可以到完全图? Solution 最少,割点,不连通,可以想到最小割. 发现,图不连通,必然存在两个点不连通. 枚举源点汇点,要让源点汇点不连通.源点汇点不能割掉 网络建图: 为了割的是边,所以要点转化成边. 对于每个x,建立x'=x+n,对于不是S.T的点(因为S.T不能割掉),x向x'连一条边权为1的边 对于原图的边e(x,y) x'->y 连接inf的边,y'->x连接inf的边. 边权保证割

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

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2182 题意:给出一个无向图,问最少删掉多少个顶点之后图变得不连通? 思路:将原图每个点拆点(i,i+n),连边<i,i+n,1>,对原图的边(u,v),连边<u+n,v,INF>,<v+n,u,INF>.然后对于每对顶点(i,j)跑最大流(i+n,j).所有最大流的最小值即为答案. struct node { int v,cap,nex

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

Cable TV Network 题目抽象:给出含有n个点顶点的无向图,给出m条边.求定点联通度   K 算法:将每个顶点v拆成 v'   v''  ,v'-->v''的容量为1.           对于原图中的边(u,v)   连边   u''--->v'    v''-->u'.    求每对定点的P(u,v);以u为源点,v为汇点. 我们只需固定一个顶点,枚举其它汇点. 1 #include <iostream> 2 #include <cstdio> 3

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

Cable TV Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4678   Accepted: 2163 Description The interconnection of the relays in a cable TV network is bi-directional. The network is connected if there is at least one interconnecti

POJ 1966 Cable TV Network

Cable TV Network Time Limit: 1000ms Memory Limit: 30000KB This problem will be judged on PKU. Original ID: 196664-bit integer IO format: %lld      Java class name: Main The interconnection of the relays in a cable TV network is bi-directional. The ne

POJ 1966 Cable TV Network(无向图的顶点连通度)

POJ 1966 Cable TV Network 链接:http://poj.org/problem?id=1966 题意:有线电视网络中,中继器的连接是双向的.如果网络中任何两个中继器之间至少有一条路,则中继器网络称为是连通的,否则中继器网络是不连通的.一个空的网络.以及只有一个中继器的网络被认为是连通的.具有n 个中继器的网络的安全系数f 被定义成: (1) f 为n,如果不管删除多少个中继器,剩下的网络仍然是连通的: (2) f 为删除最少的顶点数,使得剩下的网络不连通. 现在给定一个有

UVA 11419 SAM I AM (二分图,最小割)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2414 Problem C SAM I AM Input: Standard Input Output: Standard Output The world is in great danger!! Mental's forces have returned to Earth to eradi