隐藏页面特效

1298. 通讯问题

1|01298. 通讯问题


★   输入文件:jdltt.in   输出文件:jdltt.out   简单对比
时间限制:1 s   内存限制:128 MB

【题目描述】

一个篮球队有n个篮球队员,每个队员都有联系方式(如电话、电子邮件等)。但并不是每个队员的联系方式都公开,每个队员的联系方式只有一部分队员知道。问队员可以分成多少个小组,小组成员之间可以相互通知(包括一个队员一个组,表示自己通知自己)。

【输入格式】

 

输入文件有若干行

第一行,一个整数n,表示共有n个队员(2<=n<=100)

下面有若干行,每行2个数a、b,a、b是队员编号,表示a知道b的通讯方式。

【输出格式】

输出文件有若干行

第一行,1个整数m,表示可以分m个小组,下面有m行,每行有若干个整数,表示该小组成员编号,输出顺序按编号由小到大。

 

【样例输入】

12
1 3
2 1
2 4
3 2
3 4
3 5
4 6 
5 4
6 4
7 4
7 8
7 12
8 7
8 9
10 9
11 10

 

【样例输出】

8

1 2 3

4 6

5

7 8

9

10

11

12

 

暴力代码

#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; int n,m,k,x,y; #define N 110 int a[N][N],b[N/2][N],vis[N],jl[N],zj=0,tot=0,t1=0,qi; void bj(int z){ for(int i=0;i<zj;i++) vis[jl[i]]=1; sort(jl,jl+zj); zj=unique(jl,jl+zj)-jl; for(int i=0;i<zj;i++) b[jl[0]][i]=jl[i]; tot++; for(int i=0;i<zj;i++) jl[i]=0; zj=0; } void dfs(int u,int v){ if(vis[u]||vis[v]||u==v) return; if(v==qi) {bj(zj); return;} if(a[u][v]&&!vis[v]) { jl[zj++]=v; for(int j=1;j<=n;j++){ if(a[v][j]&&!vis[j]) dfs(v,j); } } if(u==qi&&zj>0) zj--; } int main() { freopen("jdltt.in","r",stdin); freopen("jdltt.out","w",stdout); scanf("%d",&n); while(scanf("%d%d",&x,&y)==2){ a[x][y]=1; } for(qi=1;qi<=n;qi++){ for(int j=1;j<=n;j++) if(qi!=j&&a[qi][j]){ if(!vis[qi]){ if(!vis[j]){ jl[zj++]=qi; dfs(qi,j); }else continue; }else break; } } for(int i=1;i<=n;i++) if(!vis[i]) t1++; printf("%d\n",t1+tot); for(int i=1;i<=n;i++){ if(b[i][0]!=0){ for(int j=0;b[i][j];j++){ printf("%d ",b[i][j]); } printf("\n"); } else if(!vis[i]) printf("%d\n",i); } return 0; }

 暴力代码虽然ac(数据太水),但有bug;

例如

输入数据 5 1 2 2 3 3 1 2 4 4 5 5 1 正确输出 1 1 2 3 4 5

然而 不对;

正确tarjan算法:(一样ac)

#include<cstdio> #include<iostream> #include<vector> #include<stack> #include<algorithm> #define M 100010 #define N 2010 using namespace std; vector<int> grap[M]; stack<int> s; int low[M],num[M],vis[M],instack[M]; int index,cnt,n; struct node{ int sum; int dl[N]; void px() { sort(dl+1,dl+sum+1); } };node f[N]; int cmp(const node&x,const node&y) { return x.dl[1]<y.dl[1]; } void tarjan(int v) { low[v]=num[v]=++index; s.push(v); instack[v]=1; vis[v]=1; for(int i=0;i<grap[v].size();i++){ int w=grap[v][i]; if(!vis[w]){ tarjan(w); low[v]=min(low[v],low[w]); } else if(instack[w]) low[v]=min(low[v],num[w]); } int u; if(low[v]==num[v]){ ++cnt; do { u=s.top(); f[cnt].dl[++f[cnt].sum]=u; s.pop(); instack[u]=0; }while(u!=v); } } int main() { freopen("jdltt.in","r",stdin); freopen("jdltt.out","w",stdout); int x,y; scanf("%d",&n); while(scanf("%d%d",&x,&y)==2) grap[x].push_back(y); for(int i=1;i<=n;i++) if(!vis[i])tarjan(i); printf("%d\n",cnt); for(int i=1;i<=cnt;i++) f[i].px(); sort(f+1,f+cnt+1,cmp); for(int i=1;i<=cnt;i++){ for(int j=1;j<=f[i].sum;j++) printf("%d ",f[i].dl[j]); printf("\n"); } return 0; }

 


__EOF__

本文作者shenben
本文链接https://www.cnblogs.com/shenben/p/5495887.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   神犇(shenben)  阅读(218)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
点击右上角即可分享
微信分享提示