題意:給定一些酒和一些順序,如果想喝B酒必須先喝A酒。問可不可以喝完所有的酒。
思路:拓撲排序,用map存出現過的字符串。
#include <bits/stdc++.h>
using namespace std;
int head[21000],ans;
int book[21000],m;
struct node{
int next;
int to;
}edge[21000];
void add(int u,int v)
{
edge[ans].to=v;
edge[ans].next=head[u];
head[u]=ans++;
}
bool Topo()
{
queue<int>q;
int t=0;
for (int i = 0; i<m; i++)
{
if (!book[i])
{
q.push(i);
t++;
}
}
while (!q.empty())
{
int s = q.front();
q.pop();
for (int i = head[s]; ~i; i=edge[i].next)
{
book[edge[i].to]--;
if (!book[edge[i].to])
{
t++;
q.push(edge[i].to);
}
}
}
if (t==m)
{
return true;
}
return false;
}
int main(void)
{
int T,t=1;
scanf("%d",&T);
while (T--)
{
memset(book,0,sizeof(book));
memset(head,-1,sizeof(head));
map<string,int> mp;
int n;
ans=0;
m=0;
char x[20],y[20];
scanf("%d",&n);
while (n--)
{
scanf(" %s %s",x,y);
if (!mp.count(x))
{
mp[x]=m++;
}
if (!mp.count(y))
{
mp[y]=m++;
}
add(mp[x],mp[y]);
book[mp[y]]++;
}
if (Topo())
{
printf("Case %d: Yes\n",t++);
}
else
{
printf("Case %d: No\n",t++);
}
}
return 0;
}