小希的礼物
来源:互联网 发布:蓝牙耳机配对软件 编辑:程序博客网 时间:2024/04/29 17:57
点击打开链接
这个题显然是用并查集解决的,不过我想试试用图论的方法怎么写,首先所有的顶点要连通,然后图无环,然后无重边,无自环,首先判断重边,map映射一下就可以了,确定无重边之后就用bfs判断连通,复杂度O(m),如果连通,然后通过拓扑序列判断环,如果无环,则图是一棵树,输出yes,任何一个环节出错,输出no.
下面是我的冗长但是简单的代码。
#include <set>#include <map>#include <queue>#include <string>#include <bitset>#include <cstdio>#include <vector>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;const int maxn=100005;const int maxm=2*maxn;struct Pair { int u,v; bool operator==(const Pair &t) const{ return u==t.u && v==t.v; } bool operator <(const Pair &t) const { if(u<t.u) return true; if(u==t.u && v<t.v) return true; return false; }};map<Pair,int> mp;int du[maxn];bool vis[maxn];int nodeNum;struct Edge { int from,to,next;};int pre[maxn];Edge e[maxm];int edgeNum=0;queue<int> q;queue<int> bq;int visit[maxn];void Insert(int from,int to,int i){ e[i].from=from; e[i].to=to; e[i].next=pre[from]; pre[from]=i;}bool bfs(int rt){ while(!bq.empty()) bq.pop(); bq.push(rt); memset(visit,0,sizeof(visit)); visit[rt]=1; int k=0; while(!bq.empty()) { int t=bq.front();bq.pop(); k++; for(int i=pre[t];i!=-1;i=e[i].next) { int x=e[i].to; if(visit[x]) continue; bq.push(x); visit[x]=1; } } if(k==nodeNum) return true; else return false;}bool top(){ while(!q.empty()) q.pop(); int rt=-1; for(int i=0;i<maxn;i++) { if(vis[i] && du[i]==1) { q.push(i); } if(vis[i]&&rt==-1) { rt=i; } } //cout<<rt<<endl; if(!bfs(rt)) return false; int k=0; while(!q.empty()) { int t=q.front(); q.pop(); k++; for(int i=pre[t];i!=-1;i=e[i].next) { int x=e[i].to; du[x]--; if(du[x]==1) q.push(x); } } if(k==nodeNum) return true; else return false;}int main(){ freopen("input.txt","r",stdin); int first,second; while(scanf("%d%d",&first,&second)) { mp.clear(); memset(du,0,sizeof(du)); memset(vis,0,sizeof(vis)); memset(pre,-1,sizeof(pre)); edgeNum=nodeNum=0; if(first==-1 && second==-1) break; if(first==0 && second==0) { printf("Yes\n"); continue; } Pair temp; temp.u=first; temp.v=second; mp.insert(pair<Pair,int>(temp,1)); if(!vis[first]) { nodeNum++; vis[first]=1; } if(!vis[second]) { nodeNum++; vis[second]=1; } du[first]++; du[second]++; Insert(first,second,edgeNum++); Insert(second,first,edgeNum++); bool chong=false; while(scanf("%d%d" ,&first,&second)) { if(first==0 && second==0) break; if(chong) continue; temp.u=first; temp.v=second; if(mp.count(temp)!=0) { chong=true; continue; } else { mp.insert(pair<Pair,int>(temp,1)); if(!vis[first]) { nodeNum++; vis[first]=1; } if(!vis[second]) { nodeNum++; vis[second]=1; } du[first]++; du[second]++; Insert(first,second,edgeNum++); Insert(second,first,edgeNum++); } } if(chong) printf("No\n"); else { if(top()) printf("Yes\n"); else printf("No\n"); } } return 0;}
0 0
- 小希的礼物
- hiho1505 : 小Hi和小Ho的礼物描述
- #1505 : 小Hi和小Ho的礼物
- hihocode 1505 : 小Hi和小Ho的礼物
- 七夕汇编小礼物
- 【主席树】【离线+树状数组】小崔的礼物
- 礼物说,一款小程序给你生活最好的选择
- 算法日志(2)-【小明的喷漆计划与小明的礼物】动态规划
- 天使的礼物
- 美妙的礼物
- 天使的礼物
- 给自己的礼物
- 给父母的礼物
- 麦琪的礼物
- 07年的礼物
- 浴佛节的礼物
- 礼物的利息
- 爷爷的礼物
- 面试题29:数组中出现次数超过一半的数字
- Java 打印n行杨辉三角数据
- 【VS开发】win7下让程序默认以管理员身份运行
- 用Jplayer做的一个带动画的播放器
- 最小树形图
- 小希的礼物
- Objective c中的锁 NSLock,NSConditionLock,NSRecursiveLock
- 整数在内存中的表达
- 复杂度nlog(n)之归并排序
- 文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别
- Git 一篇搞定基本操作
- vector::begin
- 【Mariadb】centos7搭建mariadb Galera集群
- 【Linux】进程的创建fork()和vfork()