真正的危机不是机器人像人一样思考,而是人像机器一样思考。 ——凉宫春日的忧郁

[Wf2015]Tours

[Wf2015]Tours

题目

给定一张n个点m条边的无向图,你需要选择一个颜色种类数k,然后用这k种颜色给每条边染色,要求对于图中任意一个简单环,每种颜色的边的数量都相同,求所有可行的k

INPUT

第一行两个正整数n,m
接下来m行,每行两个正整数x,y(1<=x<y<=n),代表一条无向边
数据保证无重边无自环

OUTPUT

一行输出所有可行的k,按递增顺序输出 6 6 1 2 2 3 1 3 1 4 2 5 3 6

SAMPLE

INPUT

6 6
1 2
2 3
1 3
1 4
2 5
3 6

OUTPUT

1 3

解题报告

其实这道题的关键在于找到每个简单环的边数,所以我们考虑如何处理简单环

显然,在一个简单环中,删去一条边,剩下的边就会变为割边

所以就可以得出做法:枚举原图非桥边,删去该边,处理出新增的桥边数量,所有数量+1的$GCD$所有的因数即为答案

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 using namespace std;
 5 inline int read(){
 6     int sum(0);char ch(getchar());
 7     for(;ch<'0'||ch>'9';ch=getchar());
 8     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
 9     return sum;
10 }
11 int n,m,tot,ans(-1);
12 int dfn[2005],low[2005],cnt,tmp;
13 int fro[2005],to[2005];
14 bool bridge[2005],vis[2005];
15 struct edge{
16     int e,id;
17     edge *n;
18 }*pre[2005],a[4005];
19 inline void insert(int s,int e,int id){
20     a[++tot].e=e;
21     a[tot].id=id;
22     a[tot].n=pre[s];
23     pre[s]=&a[tot];
24 }
25 inline void init(){
26     memset(pre,NULL,sizeof(pre));
27     memset(dfn,0,sizeof(dfn));
28     memset(low,0,sizeof(low));
29     tot=cnt=tmp=0;
30 }
31 inline void tarjan(int u,int fa){
32     dfn[u]=low[u]=++cnt;
33     for(edge *i=pre[u];i;i=i->n){
34         int e(i->e);if(e==fa)continue;
35         if(!dfn[e]){
36             tarjan(e,u);
37             low[u]=min(low[u],low[e]);
38             if(low[e]>dfn[u])bridge[i->id]=1;
39         }
40         else low[u]=min(low[u],dfn[e]);
41     }
42 }
43 inline void dfs(int u,int fa){
44     dfn[u]=low[u]=++cnt;
45     for(edge *i=pre[u];i;i=i->n){
46         int e(i->e);if(e==fa)continue;
47         if(!dfn[e]){
48             dfs(e,u);
49             low[u]=min(low[u],low[e]);
50             if(low[e]>dfn[u]&&bridge[i->id]==0)++tmp,vis[i->id]=1;
51         }
52         else low[u]=min(low[u],dfn[e]);
53     }
54 }
55 inline int gcd(int x,int y){
56     return x%y?gcd(y,x%y):y;
57 }
58 int main(){
59     n=read();m=read();
60     for(int i=1;i<=m;++i){
61         int x(read()),y(read());
62         fro[i]=x;to[i]=y;
63         insert(x,y,i);insert(y,x,i);
64     }
65     for(int i=1;i<=n;++i)
66         if(!dfn[i])
67             tarjan(i,0);
68     for(int i=1;i<=m;++i){
69         if(bridge[i]||vis[i])continue;
70         init();
71 //      for(int j=1;j<=m;++j)cout<<j<<' '<<bridge[j]<<endl;cout<<endl;//cout<<"ban "<<i<<endl;
72         for(int j=1;j<=m;++j)
73             if(j^i){//cout<<j<<' '<<fro[j]<<' '<<to[j]<<endl;
74                 insert(fro[j],to[j],j);
75                 insert(to[j],fro[j],j);
76             }
77         for(int j=1;j<=n;++j)
78             if(!dfn[j])
79                 dfs(j,0);
80 //      for(int j=1;j<=m;++j)cout<<j<<' '<<bridge[j]<<endl;cout<<endl;
81         if(ans==-1)ans=tmp+1;
82         else ans=gcd(ans,tmp+1);
83 //      cout<<tmp<<' '<<ans<<endl;
84     }
85 //  cout<<ans<<endl;
86     for(int i=1;i<=ans;++i)
87         if(ans%i==0){
88             printf("%d",i);
89             if(i^ans)putchar(' ');
90         }
91 }
View Code

 

posted @ 2017-11-03 21:23  Hzoi_Mafia  阅读(317)  评论(0编辑  收藏  举报
我们都在命运之湖上荡舟划桨,波浪起伏着而我们无法逃脱孤航。但是假使我们迷失了方向,波浪将指引我们穿越另一天的曙光。 ——死神