[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$所有的因数即为答案

 #include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
inline int read(){
int sum();char ch(getchar());
for(;ch<''||ch>'';ch=getchar());
for(;ch>=''&&ch<='';sum=sum*+(ch^),ch=getchar());
return sum;
}
int n,m,tot,ans(-);
int dfn[],low[],cnt,tmp;
int fro[],to[];
bool bridge[],vis[];
struct edge{
int e,id;
edge *n;
}*pre[],a[];
inline void insert(int s,int e,int id){
a[++tot].e=e;
a[tot].id=id;
a[tot].n=pre[s];
pre[s]=&a[tot];
}
inline void init(){
memset(pre,NULL,sizeof(pre));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
tot=cnt=tmp=;
}
inline void tarjan(int u,int fa){
dfn[u]=low[u]=++cnt;
for(edge *i=pre[u];i;i=i->n){
int e(i->e);if(e==fa)continue;
if(!dfn[e]){
tarjan(e,u);
low[u]=min(low[u],low[e]);
if(low[e]>dfn[u])bridge[i->id]=;
}
else low[u]=min(low[u],dfn[e]);
}
}
inline void dfs(int u,int fa){
dfn[u]=low[u]=++cnt;
for(edge *i=pre[u];i;i=i->n){
int e(i->e);if(e==fa)continue;
if(!dfn[e]){
dfs(e,u);
low[u]=min(low[u],low[e]);
if(low[e]>dfn[u]&&bridge[i->id]==)++tmp,vis[i->id]=;
}
else low[u]=min(low[u],dfn[e]);
}
}
inline int gcd(int x,int y){
return x%y?gcd(y,x%y):y;
}
int main(){
n=read();m=read();
for(int i=;i<=m;++i){
int x(read()),y(read());
fro[i]=x;to[i]=y;
insert(x,y,i);insert(y,x,i);
}
for(int i=;i<=n;++i)
if(!dfn[i])
tarjan(i,);
for(int i=;i<=m;++i){
if(bridge[i]||vis[i])continue;
init();
// for(int j=1;j<=m;++j)cout<<j<<' '<<bridge[j]<<endl;cout<<endl;//cout<<"ban "<<i<<endl;
for(int j=;j<=m;++j)
if(j^i){//cout<<j<<' '<<fro[j]<<' '<<to[j]<<endl;
insert(fro[j],to[j],j);
insert(to[j],fro[j],j);
}
for(int j=;j<=n;++j)
if(!dfn[j])
dfs(j,);
// for(int j=1;j<=m;++j)cout<<j<<' '<<bridge[j]<<endl;cout<<endl;
if(ans==-)ans=tmp+;
else ans=gcd(ans,tmp+);
// cout<<tmp<<' '<<ans<<endl;
}
// cout<<ans<<endl;
for(int i=;i<=ans;++i)
if(ans%i==){
printf("%d",i);
if(i^ans)putchar(' ');
}
}

最新文章

  1. node(Buffer缓存区)
  2. AngularJS in Action读书笔记4(实战篇)——创建Statistic模块
  3. jsp内置对象作业3-application用户注册
  4. 如何查询Oracle中所有用户信息
  5. super.onCreate(SavedInstanceState);
  6. WPF使用扩展屏幕
  7. 转载:centos上yum安装apache+php+mysql等
  8. SQL中的事物【转】
  9. SQL2008-字符转数字CAST和CONVERT
  10. Java基础知识强化87:BigInteger类之BigInteger加减乘除法的使用
  11. 第八十三节,CSS3动画效果
  12. python 打印文件里的内容
  13. 网站优化html关键词代码使用
  14. 【Android Developers Training】 63. 定义形状
  15. C# 获取文件下载的各种方法
  16. Laravel 1071 Specified key was too long
  17. 【python】常用第三方模块
  18. Python中Lambda表达式使用
  19. BZOJ.2069.[POI2004]ZAW(最短路Dijkstra 按位划分)
  20. 分布式任务队列Celery入门与进阶

热门文章

  1. String Mark Codeforces - 895D
  2. 题解报告:hdu 1406 完数
  3. jquery + ajax 实现多条件查询
  4. logging模块基础3
  5. Jauery 中Ajax的几种异步请求
  6. Fresco 源码分析(序)
  7. android v7包的关联
  8. (Android MVVM)使用Data Binding Library(1)
  9. pthread Win32多线程编程的一些知识和感想
  10. classpath 路径和classpath*的区别