codeforces 1131D-Gourmet choice

传送门:QAQQAQ

 

题意:有两个数组,一个数组有n个数,另一个数组有m个数。s[i][j]表示第一个数组第i个数和第二个数组第j个数的大小关系,要求构造出一种方案,使条件成立。

 

先考虑没有等于号的情况,那么就是裸的拓扑排序,现在多了一个等于号,就先进行并查集再拓扑就行了。

•注意点:1.在进行拓扑排序时一定要全部用father[x]作为节点

                2.一定要全部并查集做完以后再连边,否则可能刚连完father[x]就变了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=20001;
 4 typedef pair<int,int> pii;
 5 
 6 int p[N],a[N];
 7 int n,m,judge=0;
 8 int t[N],ans[N],b[N];
 9 char s[1020][1020];
10 vector <int> v[2080];
11 
12 int f(int x)
13 {
14     if(p[x]==x) return x;
15     return p[x]=f(p[x]);
16 }
17 
18 void unite(int x,int y)
19 {
20     int xx=f(x),yy=f(y);
21     p[yy]=p[xx];
22 }
23 
24 int main()
25 {
26     memset(b,0,sizeof(b));
27     memset(t,0,sizeof(t));
28     scanf("%d %d",&n,&m);
29     for(int i=1;i<=n+m;i++) p[i]=i;
30     for(int i=1;i<=n;i++)
31     {
32         scanf("%s",s[i]+1);
33         for(int j=1;j<=m;j++)
34         {
35             if(s[i][j]=='=') 
36             {
37                 unite(i,j+n);
38             }
39         }
40     }
41     for(int i=1;i<=n;i++)
42     {
43         for(int j=1;j<=m;j++)
44         {
45             if(s[i][j]=='>') v[f(j+n)].push_back(f(i)),t[f(i)]++;
46             else if(s[i][j]=='<') v[f(i)].push_back(f(j+n)),t[f(j+n)]++;
47         }
48     }
49     priority_queue<pii> q;
50     for(int i=1;i<=n+m;i++) if(f(i)==i) judge++;
51     for(int i=1;i<=n+m;i++)
52     {
53         if(!t[p[i]]&&!b[p[i]]) 
54         {
55             q.push(make_pair(p[i],1));
56             b[p[i]]=1;
57         }
58     }
59     int sum=0,num=1;
60     while(!q.empty())
61     {
62         int now=q.top().first,w=q.top().second;
63         q.pop(); sum++;
64         ans[now]=w;
65         for(int i=0;i<v[now].size();i++)
66         {
67             int pos=v[now][i];
68             t[pos]--;
69             if(!t[pos])
70             {
71                 q.push(make_pair(pos,w+1));
72             }
73         }
74     }
75     if(sum<judge)
76     {
77         puts("No");
78         return 0;
79     }
80     puts("Yes");
81     for(int i=1;i<=n;i++) printf("%d ",ans[p[i]]); puts("");
82     for(int i=n+1;i<=m+n;i++) printf("%d ",ans[p[i]]); puts(""); 
83     return 0;
84 }
View Code
posted @ 2019-03-23 09:26  'Clovers'  阅读(183)  评论(0编辑  收藏  举报