首页 > 代码库 > hdu-3342 Legal or Not
hdu-3342 Legal or Not
<a target=_blank href=http://www.mamicode.com/"http://acm.hdu.edu.cn/showproblem.php?pid=3342">http://acm.hdu.edu.cn/showproblem.php?pid=3342
题意:给出一些人的名次关系,问存不存在冲突的情况。
分析: 这题其实就是判断拓扑排序的过程中是否会出现环。但是为是不能用并查集我现在还是想不通,如果有知道的可以告诉一声,感激不尽!!!!
PS: 重边 需要考虑...
下面有三种做法。
1.邻接表。
大概思想就是直接拓扑排序,然后用一个数组来保存每次排序的结果,如果最后数组的大小等于n表示排序成功,如果有环,数组大小肯定小于n。具体看代码。
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define N 101 struct edges { int v; int last; }edge[N*N]; int cnt_edge; int node[N]; int in[N],num[N]; int n,m,cnt; queue<int>q; void add_edge(int x,int y) { edge[cnt_edge].last=node[x]; edge[cnt_edge].v=y; node[x]=cnt_edge++; } void clear() { cnt_edge=0; cnt=0; memset(num,0,sizeof(num)); memset(in,0,sizeof(in)); memset(node,-1,sizeof(node)); while(!q.empty()) q.pop(); } int top_sort() { int now,next,j; while(!q.empty()) { now=q.front(); num[++cnt]=now; q.pop(); for(j=node[now];j!=-1;j=edge[j].last) { next=edge[j].v; in[next]--; if(in[next]==0) q.push(next); } } if(cnt==n) return 0; else return 1; } int main() { while(scanf("%d%d",&n,&m),n+m) { clear(); int x,y; while(m--) { scanf("%d%d",&x,&y); add_edge(x,y); in[y]++; } int i; for(i=0;i<n;i++) { if(!in[i]) q.push(i); } if(top_sort()) printf("NO\n"); else printf("YES\n"); } return 0; }
2.邻接矩阵。 判断环的方法是: 在某一次排序的过程中找不到入度为 0 的点,即说明有环。实现可能比邻接表简单点。
#include<cstdio> #include<cstring> #define N 101 int map[N][N],in[N],n,flag; int top_sort() { for(int i=0;i<n;i++) { flag=1; for(int j=0;j<n;j++) { if(in[j]==0) { in[j]=-1; //删掉一条边 flag=0; for(int k=0;k<n;k++) if(map[j][k]) //与之相连的全部删除 in[k]--; break; } } if(flag) break; } return flag; } int main() { int m,i,j,k,x,y; while(scanf("%d%d",&n,&m),n+m) { memset(map,0,sizeof(map)); memset(in,0,sizeof(in)); while(m--) { scanf("%d%d",&x,&y); if(!map[x][y]) { map[x][y]=1; in[y]++; } } if(top_sort()) printf("NO\n"); else printf("YES\n"); } return 0; }
3.floyed 时间用的蛮多, 就是用二维数组表示两点连通,floyed后,枚举自己跟自己如果连通,表示有环。
#include<cstdio> #include<cstring> #define N 101 int map[N][N],n,flag; void floyed() { for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) map[i][j]=map[i][j]||(map[i][k]&&map[k][j]); for(int i=0;i<n;i++) if(map[i][i]) {printf("NO\n"); return;} printf("YES\n"); } int main() { int m,i,j,k,x,y; while(scanf("%d%d",&n,&m),n+m) { memset(map,0,sizeof(map)); while(m--) { scanf("%d%d",&x,&y); map[x][y]=1; } floyed(); } return 0; }
#include<cstdio> #include<cstring> #define N 101 int map[N][N],n,flag; void floyed() { for(int k=0;k<n;k++) for(int i=0;i<n;i++) for(int j=0;j<n;j++) map[i][j]=map[i][j]||(map[i][k]&&map[k][j]); for(int i=0;i<n;i++) if(map[i][i]) {printf("NO\n"); return;} printf("YES\n"); } int main() { int m,i,j,k,x,y; while(scanf("%d%d",&n,&m),n+m) { memset(map,0,sizeof(map)); while(m--) { scanf("%d%d",&x,&y); map[x][y]=1; } floyed(); } return 0; }
hdu-3342 Legal or Not
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。