您的位置:首页 > 其它

【lightoj1003 - Drunk】

2018-01-20 17:30 260 查看

–>传送门

有m个关系格式是a b;表示想要喝b必须喝a,问一个人是否喝醉即看一个人是否能把所有种类的饮料喝完,能输出Yes,不能输出No;

其实就是有向图判断是否存在环,可以用拓扑排序来求,用map离散化。

具体方法是将入度为0的点push进queue,push进一个cnt+1,最后判断cnt == n ?即为最后是否留下环。

#include<bits/stdc++.h>
using namespace std;
const int N = 10010;
int cnt,cas = 0;
int head
,in_deg
;
struct edge
{
int to, next;
} g[10010];
void add_edge(int u,int v)
{
g[cnt].to = v, g[cnt].next = head[u], head[u] = cnt++;
}
bool top(int num)
{
queue<int> Q;
int i,cnt = 0;
for(i = 0; i<num; i++)
if(in_deg[i] == 0) Q.push(i),cnt++;
while(!Q.empty())
{
int u = Q.front();
Q.pop();
for(i = head[u]; i != -1; i = g[i].next)
{
if(--in_deg[g[i].to] == 0) Q.push(g[i].to),cnt++;
}
}
return cnt == num;
}
int main()
{
int t, n;
char s1[10], s2[10];
cin>>t;
while(t--)
{
scanf("%d", &n);
memset(in_deg, 0, sizeof(in_deg));
memset(head, -1, sizeof(head));
map<string, int>M;
int num = 0;
cnt = 0;
while(n--)
{
scanf("%s %s", s1, s2);
if(M.find(s1) == M.end()) M[s1] = num++;
if(M.find(s2) == M.end()) M[s2] = num++;
in_deg[M[s2]]++;
add_edge(M[s1], M[s2]);
}
printf("Case %d: ", ++cas);
if(top(num)) puts("Yes");
else puts("No");
}
return 0;
}


还可以用并查集写,祖先相同则说明有环

include <bits/stdc++.h>
using namespace std;
int par[20005];
int F(int n)
{
int i = n;
while(par
!= n)
n = par
;
par[i] = n;
return n;
}
int main()
{
int t, n, i;
cin>>t;
int cas = 0;
while(t--)
{
map<string, int> M;
cin>>n;
char s1[20], s2[20];
int num = 1;
for(i = 1; i <= 20000; i++) par[i] = i;
bool f = 0;
while(n--)
{
scanf("%s%s", s1, s2);
if(M[s1] == 0) M[s1] = num++;
if(M[s2] == 0) M[s2] = num++;
int aa = F(M[s1]);
int bb = F(M[s2]);
if(aa == bb) f = 1;
else par[aa] = bb;
}
printf("Case %d: %s\n", ++cas, f == 1? "No": "Yes");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: