• Rikka with Graph(hdu5631)


    Rikka with Graph

     
     Accepts: 123
     
     Submissions: 525
     Time Limit: 2000/1000 MS (Java/Others)
     
     Memory Limit: 65536/65536 K (Java/Others)
    问题描述
    众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:
    
    给出一张 nn 个点 n+1n+1 条边的无向图,你可以选择一些边(至少一条)删除。
    
    现在勇太想知道有多少种方案使得删除之后图依然联通。
    
    当然,这个问题对于萌萌哒六花来说实在是太难了,你可以帮帮她吗?
    输入描述
    第一行一个整数表示数据组数 T(T leq 30)T(T30)。
    
    每组数据的第一行是一个整数 n(n leq 100)n(n100)。
    
    接下来 n+1n+1 行每行两个整数 u,vu,v 表示图中的一条边。
    输出描述
    对每组数据输出一行一个整数表示答案。
    输入样例
    1
    3
    1 2
    2 3
    3 1
    1 3
    
    输出样例
    9
    思路:并查集,最短路,组合,先用并查集,找一到n-1条可以连通所有点的边,同时也判断了,整个图是否连通,然后剩下的2条边,分别以该边的一个点为起点
    另一个位终点,用最短路搜连接这两个点的最小环由哪些边组成,然后记录个环的共同边ans,和两个环各自的边nk,mk,最后答案就是nk+mk-ans+nk*mk-ans*ans;nk+mk-ans--去掉一个边的方案,应为环去一边,所有点还是连通的。

    nk*mk-ans*ans--去两个边的可能每个环出一个边方案为nk*mk,因为两个环重合的地方不能去,所以减ans*ans;
    这个复杂度为(N*N)AC 0ms
      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<string.h>
      5 #include<queue>
      6 #include<vector>
      7 #include<set>
      8 #include<map>
      9 #include<math.h>
     10 using namespace std;
     11 struct node
     12 {
     13     int x;
     14     int y;
     15 };
     16 vector<int>dian[110];
     17 node bian[110];
     18 bool flag[110];
     19 int bin[110];
     20 int shen[110];
     21 int dj[110];
     22 int TWO[200];
     23 int HH[110];
     24 int mapp[110][110];
     25 int ma[110][110];
     26 int pre[110];
     27 int DD[110];
     28 int CC[110];
     29 map<int,int>my;
     30 int cha(int x,int y);
     31 void dfs(int n,int z);
     32 void ME()
     33 { int i,j;
     34     memset(flag,0,sizeof(flag));
     35     for(i=0; i<110; i++)
     36     {
     37         bin[i]=i;
     38         shen[i]=1;
     39     }
     40     for(i=0; i<110; i++)
     41     {
     42         for(j=0; j<110; j++)
     43         {
     44             mapp[i][j]=200;
     45         }
     46     }
     47 } void dis(int n,int k);
     48 int main(void)
     49 {
     50     int i,j,k,p,q,n;
     51     //freopen("data.in","r",stdin);
     52     //freopen("wrong.out","w",stdout);
     53     scanf("%d",&k);
     54     while(k--)
     55     {
     56         ME();scanf("%d",&n);
     57         int cnt=0;
     58         for(i=0; i<=n; i++)
     59         {
     60             scanf("%d %d",&bian[i].x,&bian[i].y);
     61             int s=cha(bian[i].x,bian[i].y);
     62             if(s==1)
     63             {
     64                 TWO[cnt++]=i;
     65             }
     66         }
     67         for(i=1; i<=n; i++)
     68         {
     69             for(j=i; bin[j]!=j;)
     70                 j=bin[j];
     71             HH[i]=j;
     72         }
     73         for(i=2; i<=n; i++)
     74         {
     75             if(HH[i]!=HH[1])
     76             {
     77                 break;
     78             }
     79         }
     80         if(i!=n+1)
     81         {
     82             printf("0
    ");
     83         }
     84         else
     85         {
     86             int vx=bian[TWO[0]].x;
     87             int vy=bian[TWO[0]].y;
     88             int vxx=bian[TWO[1]].x;
     89             int vyy=bian[TWO[1]].y;
     90             for(i=0; i<=n; i++)
     91             {
     92                 if(i!=TWO[0]&&i!=TWO[1])
     93                 {
     94                     mapp[bian[i].x][bian[i].y]=1;
     95                     mapp[bian[i].y][bian[i].x]=1;
     96                     ma[bian[i].x][bian[i].y]=i;
     97                     ma[bian[i].y][bian[i].x]=i;
     98                 }
     99             }
    100                 dis(vxx,n);
    101                 int va=pre[vyy];int hh=vyy;
    102                 memset(DD,0,sizeof(DD));
    103                 while(va!=-1)
    104                 {
    105                     DD[va]=1;
    106                     int xx=bian[va].x;
    107                     int yy=bian[va].y;
    108                     if(hh!=xx)
    109                     {va=pre[xx];hh=xx;}
    110                     else {va=pre[yy];hh=yy;}
    111 
    112                 }
    113             DD[TWO[1]]=1;
    114                  dis(vx,n);
    115                  va=pre[vy];hh=vy;
    116                 memset(CC,0,sizeof(CC));
    117                while(va!=-1)
    118                 {
    119                     CC[va]=1;
    120                     int xx=bian[va].x;
    121                     int yy=bian[va].y;
    122                     if(hh!=xx)
    123                     {va=pre[xx];hh=xx;}
    124                     else {va=pre[yy];hh=yy;}
    125 
    126                 }
    127             CC[TWO[0]]=1;
    128             int ans=0;int nk=0;int mk=0;
    129             for(i=0;i<=n;i++)
    130             {
    131                 if(CC[i]&&DD[i])
    132                 {
    133                     ans++;
    134                 }
    135                 if(CC[i])
    136                 {
    137                     nk++;
    138                 }
    139                 if(DD[i])
    140                 {
    141                     mk++;
    142                 }
    143             }
    144             int sum=nk+mk-ans+nk*mk-ans*ans;
    145             printf("%d
    ",sum);
    146         }}return 0;    }
    147    int cha(int x,int y)
    148     {
    149         int i,j;
    150         int xx,yy;
    151         for(xx=x; bin[xx]!=xx;)
    152             xx=bin[xx];
    153         for(yy=y; bin[yy]!=yy;)
    154             yy=bin[yy];
    155         if(xx==yy)
    156         {
    157             return 1;
    158         }
    159         if(xx!=yy)
    160         {
    161             if(shen[xx]>shen[yy])
    162             {
    163                 shen[xx]+=shen[yy];
    164                 bin[yy]=xx;
    165             }
    166             else
    167             {
    168                 shen[yy]+=shen[xx];
    169                 bin[xx]=yy;
    170             }
    171         }
    172         return 0;
    173     }
    174     void dis(int n,int k)
    175     {
    176         fill(dj,dj+110,1000);
    177         fill(pre,pre+110,-1);
    178         dj[n]=0;int i,j;
    179         memset(flag,0,sizeof(flag));
    180         pre[n]=-1;
    181         while(true)
    182         {
    183             int l=-1;
    184             for(i=1; i<=k; i++)
    185             {
    186                 if((l==-1||(dj[l]>dj[i]))&&!flag[i])
    187                 {
    188                     l=i;
    189                 }
    190             }
    191             if(l==-1)
    192             {
    193                 break;
    194             }
    195             flag[l]=true;
    196             for(i=1; i<=k; i++)
    197             {
    198                 if(mapp[l][i]+dj[l]<dj[i])
    199                 {
    200                     pre[i]=ma[l][i];
    201                     dj[i]=mapp[l][i]+dj[l];
    202                 }
    203             }
    204         }
    205     }

    思路2:让 nn 个点联通最少需要 n-1n1 条边,所以最多只能删除两条边,我们可以枚举删除的这两条边(或者唯一的一条边),然后并查集判断连通性就好了。时间复杂度 O(n^3)

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<stdlib.h>
      5 #include<string.h>
      6 #include<math.h>
      7 #include<queue>
      8 #include<stack>
      9 #include<iomanip>
     10 #include<cstdio>
     11 #include<map>
     12 #include<set>
     13 #include <cmath>
     14 #include <ctime>
     15 #include <cstring>
     16 #include <cctype>
     17 #include <cassert>
     18 #include<vector>
     19 using namespace std;
     20 struct node
     21 {
     22     int x;
     23     int y;
     24 };
     25 node dian[200];
     26 vector<int>vec[102];
     27 bool flag[102];
     28 bool flag1[103];
     29 bool flag2[103];
     30 int bincha[102];
     31 int shendu[102];
     32 int huanyuan[102];
     33 int an=0;
     34 void me()
     35 {
     36     memset(flag1,0,sizeof(flag));
     37     memset(flag2,0,sizeof(flag1));
     38     memset(flag,0,sizeof(flag));
     39     int i,j;
     40     for(i=0; i<102; i++)
     41     {
     42         bincha[i]=i;
     43         shendu[i]=1;
     44     }
     45 }
     46 void BB(int a,int b)
     47 {
     48     int x,y;
     49     for(x=a; bincha[x]!=x;)
     50     {
     51         x=bincha[x];
     52     }
     53     for(y=b; bincha[y]!=y;)
     54     {
     55         y=bincha[y];
     56     }
     57     if(x!=y)
     58     {
     59         if(shendu[x]>shendu[y])
     60         {
     61             shendu[x]+=shendu[y];
     62             bincha[y]=x;
     63         }
     64         else
     65         {
     66             shendu[y]+=shendu[x];
     67             bincha[x]=y;
     68         }
     69     }
     70 }
     71 void slove (int s)
     72 {
     73     int i,j,k,m,n;
     74     int fl=0;int nn,mm;
     75     for(i=0; i<=s; i++)
     76     {
     77         for(j=i+1; j<=s; j++)
     78         {
     79             for(int z=0; z<102; z++)
     80             {
     81                 bincha[z]=z;
     82                 shendu[z]=1;
     83             }
     84             for(m=0; m<=s; m++)
     85             {
     86                 if(m!=i&&m!=j)
     87                 {
     88                     BB(dian[m].x,dian[m].y);
     89                 }
     90             }
     91             for(m=1;m<=s; m++)
     92             {
     93                 for(n=m; bincha[n]!=n;)
     94                     n=bincha[n];
     95                 huanyuan[m]=n;
     96             }
     97             for(n=2; n<=s; n++)
     98             {
     99                 if(huanyuan[n]!=huanyuan[1])
    100                 {
    101                     break;
    102                 }
    103             }
    104             if(n==s+1)
    105             {
    106                 an++;
    107                 flag[i]=true;
    108                 flag[j]=true;
    109 
    110             }
    111         }
    112         if(fl)
    113             break;
    114     }int ans[102];int cnt=0;
    115     int bns[102];int cnt1=0;
    116 
    117 }
    118 int main(void)
    119 {
    120     int i,j,k,p,q;
    121     int N;  //freopen("data.in","r",stdin);
    122     //freopen("wrong.out","w",stdout);
    123     cin>>k;
    124     while(k--)
    125     {  scanf("%d",&N) ;an=0;
    126         for(i=0; i<102; i++)
    127             vec[i].clear();
    128         me();
    129 
    130         for(i=0; i<N+1; i++)
    131         {
    132             cin>>p>>q;
    133             dian[i].x=p;
    134             dian[i].y=q;
    135             vec[p].push_back(q);
    136             vec[q].push_back(p);
    137             BB(p,q);
    138         }
    139         for(i=1;i<=N;i++)
    140         {
    141             for(j=i;bincha[j]!=j;)
    142                 j=bincha[j];
    143             huanyuan[i]=j;
    144         }
    145         for(i=2;i<=N;i++)
    146         {
    147             if(huanyuan[i]!=huanyuan[1])
    148             {
    149                 break;
    150             }
    151         }
    152         if(i!=N+1)
    153         {
    154             printf("0
    ");
    155         }
    156         else
    157         {
    158             slove(N);
    159             for(i=0;i<=N;i++)
    160             {
    161                 if(flag[i])
    162                 {
    163                     an++;
    164                 }
    165             }
    166             printf("%d
    ",an);
    167         }
    168 
    169     }
    170     return 0;
    171 }
    N*N*N
     
    油!油!you@
  • 相关阅读:
    左耳听风-ARTS-第4周(2019/4/21-2019/4/27)
    Java集合总结
    Zuul网关总结
    左耳听风-ARTS-第3周(2019/4/7-2019/4/13)
    左耳听风-ARTS-第2周(2019/3/31-2019/4/6)
    Java泛型相关总结(下)
    左耳听风-ARTS-第1周
    去长江边走走,看看
    第1记
    c#发送邮件
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5212927.html
Copyright © 2020-2023  润新知