hdu 3342 Legal or Not(DAG的拓扑排序)
来源:互联网 发布:手机单机小游戏知乎 编辑:程序博客网 时间:2024/06/06 07:43
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3342
题意:给出一个有向图,判断是否有环,也就是问是否是有向无环图(DAG),是则输出YES,否则输出NO,所以可以用是否存在拓扑序列来判断。
解题方案:用入度表的方法,即每次找入度为0的点,然后删掉这个点和由这个点发出的边,循环结束以后判断是不是每个点的入度都为0了,如果是则该DAG存在拓扑序列,否则说明存在环,则不存在拓扑序列。
解法一:入度数组+邻接表(vector 动态建表,建表时需要新建对象)
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define FOR(i,k,n) for(int i=k;i<n;i++)#define FORR(i,k,n) for(int i=k;i<=n;i++)#define scan(a) scanf("%d",&a)#define scann(a,b) scanf("%d%d",&a,&b)#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)#define mst(a,n) memset(a,n,sizeof(a))#define ll long long#define N 105#define mod 1000000007#define INF 0x3f3f3f3fconst double eps=1e-8;const double pi=acos(-1.0);int n,m;int in[N];vector<int> mp[N];queue<int> q;int solve(){ while(!q.empty()) q.pop(); vector<int> v; FOR(i,0,n) if(in[i]==0) v.push_back(i); FOR(i,0,v.size()) { q.push(v[i]); while(!q.empty()) { int cur=q.front(); q.pop(); FOR(j,0,mp[cur].size()) { in[mp[cur][j]]--; if(in[mp[cur][j]]==0) q.push(mp[cur][j]); } } } FOR(i,0,n) if(in[i]) return 0; return 1;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scann(n,m)&&n) { FOR(i,0,N) mp[i].clear(); mst(in,0); FOR(i,0,m) { int u,v; scann(u,v); mp[u].push_back(v);//建邻接表时需动态新建对象 in[v]++; } //FOR(i,0,n) printf("%d ",in[i]); int ans=solve(); if(ans) printf("YES\n"); else printf("NO\n"); } return 0;}
解法二:入度数组+邻接表(链式前向星 静态建表,采用静态数组,一次性内存申请),耗时和用vector一样都是31ms,并没有变快啊??是因为vector效率已经很高了?
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <vector>#include <queue>#include <stack>#include <set>#include <map>using namespace std;#define FOR(i,k,n) for(int i=k;i<n;i++)#define FORR(i,k,n) for(int i=k;i<=n;i++)#define scan(a) scanf("%d",&a)#define scann(a,b) scanf("%d%d",&a,&b)#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)#define mst(a,n) memset(a,n,sizeof(a))#define ll long long#define N 105#define mod 1000000007#define INF 0x3f3f3f3fconst double eps=1e-8;const double pi=acos(-1.0);int n,m;int in[N];queue<int> q;struct Edge{ int to; //int w; int next;}E[N];int head[N];//顶点i发出的输入数据中最后一条边的编号int solve(){ while(!q.empty()) q.pop(); vector<int> v; FOR(i,0,n) if(in[i]==0) v.push_back(i); FOR(i,0,v.size()) { q.push(v[i]); while(!q.empty()) { int cur=q.front(); q.pop(); for(int j=head[cur];j!=-1;j=E[j].next) { int to=E[j].to; in[to]--; if(in[to]==0) q.push(to); } } } FOR(i,0,n) if(in[i]) return 0; return 1;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scann(n,m)&&n) { mst(E,0); mst(head,-1); mst(in,0); FOR(i,0,m) { int u,v; scann(u,v); E[i].to=v; E[i].next=head[u]; head[u]=i; in[v]++; } //FOR(i,0,n) printf("%d ",in[i]); int ans=solve(); if(ans) printf("YES\n"); else printf("NO\n"); } return 0;}
0 0
- hdu 3342 Legal or Not(DAG的拓扑排序)
- 【hdu 3342】【拓扑排序(DAG) BFS】Legal or Not
- 【拓扑排序】hdu 3342 Legal or Not
- 【HDU】3342 Legal or Not 拓扑排序
- hdu 3342 Legal or Not 拓扑排序
- HDU 3342 Legal or Not (拓扑排序)
- 拓扑排序 HDU 3342 Legal or Not
- hdu 3342 Legal or Not 拓扑排序
- HDU 3342 Legal or Not (拓扑排序)
- hdu 3342 Legal or Not(拓扑排序)
- hdu 3342 Legal or Not ( 拓扑排序 )
- hdu 3342 Legal or Not(拓扑排序)
- hdu 3342 Legal or Not (拓扑排序)
- [ACM] hdu 3342 Legal or Not (拓扑排序)
- hdu 3342 Legal or Not (拓扑排序)
- HDU 3342 -- Legal or Not(拓扑排序)
- HDU-3342 Legal or Not(拓扑排序)
- HDU 3342 Legal or Not (拓扑排序)
- 解决iframe作为子窗口,刷新后iframe页面跳转到其它页面的问题
- python生成opencv正样本和负样本描述文件
- Android 选择图片、上传图片
- 设计模式之适配器模式
- A hard Aoshu Problem HDU
- hdu 3342 Legal or Not(DAG的拓扑排序)
- Mybatis Generator最完整配置详解
- mysqldump命令操作
- SpringBoot入门demo(一)
- .net 开发日志
- 使用JVisualVM进行性能分析
- 这两天写了两个开源小工具
- 使用MSCK命令修复Hive表分区
- 贪心问题--过河问题