zoukankan      html  css  js  c++  java
  • POJ 1966

    求的是无向图的点连通度。开始便想到网络流,既然选的是点,当然就要拆点加边了。但无论如何也不敢往枚举源汇点的方向想,因为网络流复习度很高。看看网上大牛的,都是枚举,再看数据,原来N才50个点,枚举无压力啊。看来自己以后要注意分析一下复杂度了。

    总结:

    1)无向图点连通度

    看来没有什么好的算法。网络流。把点i拆成i->i‘容量自然是1,把无向图的边也拆成两条有向边i'->j,j'->i,容量为无穷。然后,枚举求s'->t的最小割就可了。

    2)有向图点连通度

    这个更简单了,单纯拆点建图就可以了。

    3)无向图边连通度。

    可以用store-wanger求最小割。边权为1

    4)有向图边连通度

    就是网络流求最小割

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 const int INF=0x3f3f3f3;
      8 const int MAXN=120    ;
      9 const int MAXM=15000;
     10 
     11 struct Node{
     12     int from,to,next;
     13     int cap;
     14 }edge[MAXM];
     15 int tol;
     16 
     17 int dep[MAXN];
     18 int head[MAXN];
     19 bool maze[MAXN][MAXN];
     20 int n,m;
     21 void init(){
     22     tol=0;
     23     memset(head,-1,sizeof(head));
     24 }
     25 void addedge(int u,int v,int w){
     26     edge[tol].from=u;
     27     edge[tol].to=v; edge[tol].cap=w;  edge[tol].next=head[u];
     28     head[u]=tol++;
     29     edge[tol].from=v;
     30     edge[tol].to=u;
     31     edge[tol].cap=0;
     32     edge[tol].next=head[v];
     33     head[v]=tol++;
     34 }
     35 
     36 int BFS(int start,int end){
     37     int que[MAXN];
     38     int front,rear; front=rear=0;
     39     memset(dep,-1,sizeof(dep));
     40     que[rear++]=start;
     41     dep[start]=0;
     42     while(front!=rear){
     43         int u=que[front++];
     44         if(front==MAXN)front=0;
     45         for(int i= head[u];i!=-1; i=edge[i].next){
     46             int v=edge[i].to;
     47             if(edge[i].cap>0&& dep[v]==-1){
     48                 dep[v]=dep[u]+1;
     49                 que[rear++]=v;
     50                 if(rear>=MAXN) rear=0;
     51                 if(v==end)return 1;
     52             }
     53         }
     54     }
     55     return 0;
     56 }
     57 int dinic(int start,int end){
     58     int res=0;
     59     int top;
     60     int stack[MAXN];
     61     int cur[MAXN];
     62     while(BFS(start,end)){
     63         memcpy(cur,head, sizeof(head));
     64         int u=start;
     65         top=0;
     66         while(1){
     67             if(u==end){
     68                 int min=INF;
     69                 int loc;
     70                for(int i=0;i<top;i++)
     71                   if(min>edge [stack[i]].cap) {
     72                       min=edge [stack[i]].cap;
     73                       loc=i;
     74                   }
     75                 for(int i=0;i<top;i++){
     76                     edge[stack[i]].cap-=min;
     77                     edge[stack[i]^1].cap+=min;
     78                 }
     79                 res+=min;         
     80                 top=loc;               
     81                 u=edge[stack[top]].from;
     82             }
     83             for(int i=cur[u]; i!=-1; cur[u]=i=edge[i].next)
     84               if(edge[i].cap!=0 && dep[u]+1==dep[edge[i].to])
     85                  break;
     86             if(cur[u] !=-1){
     87                 stack [top++]= cur[u];
     88                 u=edge[cur[u]].to;
     89             }
     90             else{
     91                 if(top==0) break;
     92                 dep[u]=-1;
     93                 u= edge[stack [--top] ].from;
     94             }
     95         }
     96     }
     97     return res;
     98 }
     99 
    100 void build(){
    101         init();
    102         for(int i=0;i<n;i++){
    103             for(int j=0;j<n;j++){
    104                 if(i==j)
    105                 addedge(i*2,i*2+1,1);
    106                 else if(maze[i][j]){
    107                     addedge(i*2+1,j*2,INF);
    108                 }
    109             }
    110         }
    111 
    112 }
    113 
    114 int main(){
    115     int u,v;
    116     while(scanf("%d%d",&n,&m)!=EOF){
    117           memset(maze,false,sizeof(maze));
    118         for(int i=0;i<m;i++){
    119             scanf(" (%d,%d)",&u,&v);
    120             maze[u][v]=maze[v][u]=true;
    121         }
    122         int ans=INF;
    123         for(int i=0;i<n;i++){
    124             for(int j=i+1;j<n;j++){
    125                 build();
    126                 if(!maze[i][j]){
    127                 int res=dinic(i*2+1,j*2);
    128                 if(res<ans) ans=res;
    129                 if(ans==0) break;
    130                 }
    131             }
    132             if(ans==0) break;
    133         }
    134         if(ans>=n){ printf("%d
    ",n); continue; }
    135         printf("%d
    ",ans);
    136     }
    137     return 0;
    138 }
    View Code
  • 相关阅读:
    注册表解锁
    Windows错误代码大全 2
    硬盘数据线的问题
    vs2010与C#4.0新特性
    (转载)C语言负数的移位运算
    (转载)看C语言编码转换负数的二进制表示方法
    (转载)C语言右移运算符的问题(特别当与取反运算符一起时)
    (转载)Qt中使用cout输出的方法
    (转载)QPainter的用法
    (转载)Qt计算MD5
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3860603.html
Copyright © 2011-2022 走看看