zoukankan      html  css  js  c++  java
  • LA5135图论+ 割点性质运用

      1 /*
      2 LA5135图论
      3 割点性质运用
      4 
      5 关键:割顶出设置逃生点是不划算的。
      6 这道题的思路算是比较简单,没有推导证明的成分,是BCC性质的运用
      7 注意,当整张图是BCC时,至少要设置两个逃生点,这个也算是考点,开始没想到,下次注意
      8 */
      9 #include <stdio.h>
     10 #include <stdlib.h>
     11 #include <string.h>
     12 #include <math.h>
     13 #include <ctype.h>
     14 #include <string>
     15 #include <iostream>
     16 #include <sstream>
     17 #include <vector>
     18 #include <queue>
     19 #include <stack>
     20 #include <map>
     21 #include <list>
     22 #include <set>
     23 #include <algorithm>
     24 #define rec(i,n) for(int i=1;i<=n;i++)
     25 #define INF 0x3f3f3f3f
     26 using namespace std;
     27 
     28 const int maxn = 101000 ;
     29 struct edge
     30 {
     31     int u,v,cap,pre;//cap表示花费
     32     edge(int u=0,int v=0):u(u),v(v){}
     33 }Edge[maxn];//注意开两倍的边
     34 int head[maxn],next[maxn],nedge;//表示读入的边的个数
     35 void addedge(int u,int v)
     36 {
     37     Edge[++nedge]=edge(u,v);//边从1开始编号
     38     next[nedge]=head[u];
     39     head[u]=nedge;
     40 }
     41 void edgeinit()//添边之前要初始化
     42 {
     43     nedge=0;
     44     memset(head,-1,sizeof(head));
     45 }
     46 int pre[maxn],iscut[maxn],bccno[maxn],dfs_clock,bcc_cnt;
     47 vector<int> bcc[maxn];
     48 stack<edge>S ;
     49 
     50 int dfs(int u,int fa)
     51 {
     52     int lowu=pre[u]=++dfs_clock;
     53     int child=0;
     54     for(int i=head[u];i!=-1;i=next[i])
     55     {
     56         int v=Edge[i].v;
     57         edge e=(edge){u,v};
     58         if (!pre[v])
     59         {
     60             S.push(e);
     61             child++;
     62             int lowv=dfs(v,u);//这时,u是父节点
     63             lowu=min(lowu,lowv);
     64             if (lowv>=pre[u])
     65             {
     66                 iscut[u]=true;
     67                 bcc_cnt++;bcc[bcc_cnt].clear();
     68                 for(;;)
     69                 {
     70                     edge x=S.top();S.pop();
     71                     if(bccno[x.u]!=bcc_cnt){bcc[bcc_cnt].push_back(x.u);bccno[x.u]=bcc_cnt;}
     72                     if(bccno[x.v]!=bcc_cnt){bcc[bcc_cnt].push_back(x.v);bccno[x.v]=bcc_cnt;}
     73                     if(x.u==u&&x.v==v) break;
     74                 }
     75             }
     76         }
     77         else if (pre[v]<pre[u] && v!=fa)
     78         {
     79             S.push(e);
     80             lowu=min(lowu,pre[v]);
     81         }
     82     }
     83     if(fa<0 && child==1) iscut[u]=0;
     84     return lowu;
     85 }
     86 
     87 void find_bcc(int n)//n是定点个数
     88 {
     89     memset(pre,0,sizeof(pre));
     90     memset(iscut,0,sizeof(iscut));
     91     memset(bccno,0,sizeof(bccno));
     92     dfs_clock=bcc_cnt=0;
     93     for(int i=1;i<=n;i++)
     94     {
     95         if(!pre[i]) dfs(i,-1);
     96     }
     97 }
     98 void solve(int cas,int m)
     99 {
    100     long long n1=0,n2=1;
    101     if (bcc_cnt==1) n1=2,n2=(long long)bcc[1].size()*(bcc[1].size()-1)/2;
    102     else
    103     {
    104         for(int i=1;i<=bcc_cnt;i++)//枚举每个bcc
    105         {
    106             int cnt=0;//一个bcc中割顶的个数是1或0
    107             for(int j=0;j<bcc[i].size();j++)
    108             if(iscut[bcc[i][j]]) cnt++;
    109             if(cnt==1) n1++,n2=n2*(long long)(bcc[i].size()-1);
    110         }
    111     }
    112     cout<<"Case "<<cas<<": "<<n1<<" "<<n2<<endl;
    113     return;
    114 }
    115 int main()
    116 {
    117     int n,cas=0;
    118 
    119     while(cin>>n && n!=0)
    120     {
    121         cas++;
    122         edgeinit();
    123         int m=0;
    124         for(int i=1;i<=n;i++)
    125         {
    126             int u,v;
    127             cin>>u>>v;
    128             addedge(u,v);addedge(v,u);
    129             m=max(m,u);m=max(m,v);//最大的点
    130         }
    131         find_bcc(m);
    132         solve(cas,m);
    133     }
    134     return 0;
    135 }
  • 相关阅读:
    为什么你应该(从现在开始就)写博客
    ASP.net 中使用Flexigrid详细教程之二直接使用数据库数据(有图有真相)
    保护眼睛的方法 (眼睛累了吗 来看看吧)
    程序员不如快递员?
    项目管理界面
    地址栏射击游戏!对,你没看错,就是在地址栏上玩的游戏,有图有真相!
    书写是为了更好的思考
    IT人员如何找到自己的时间?
    std::mem_fun_ref,mem_fun1_ref分析
    __declspec(selectany) 的作用是什么
  • 原文地址:https://www.cnblogs.com/little-w/p/3570214.html
Copyright © 2011-2022 走看看