Gym 101142C CodeCoder vs TopForces 【dfs】
题目:
题目大意:
有n个人,每一个人有一个cc分和tf分
若A比B的任何一项分数高,则代表A可以赢B
同时,这个赢具有传递性(很重要!!!)
即:A->B,B->C,则可以认为 A->C
现在问从1~n每一个人可以赢多少个人
大致思路:
可以分别用把这两次的分数建成一张有向图,A可以到B则代表A可以赢B。
然后从分数较小的人开始进行DFS计数,这里的DFS的visit数组可以不清空。
记的数为目前一共访问了多少个节点,然后这一个点可到的点一定为这个数减去1(因为这些记数的点中包含自身)。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+7; 4 struct Node{ 5 int cc,tf,id; 6 }node[maxn]; 7 int cnt[maxn]; 8 int tot=0; 9 vector<int> g[maxn]; 10 bool visit[maxn]; 11 bool cmp1(Node a,Node b) 12 { 13 return a.cc<b.cc; 14 } 15 bool cmp2(Node a,Node b) 16 { 17 return a.tf<b.tf; 18 } 19 void dfs(int x) 20 { 21 if(!visit[x]) 22 tot++; 23 visit[x]=true; 24 int u; 25 for(int i=0;i<g[x].size();++i){ 26 u=g[x][i]; 27 if(!visit[u]) 28 dfs(u); 29 } 30 } 31 void print(int n) 32 { 33 for(int i=1;i<=n;++i){ 34 cout<<i<<" "; 35 for(int j=0;j<g[i].size();++j) 36 cout<<g[i][j]<<" "; 37 cout<<endl; 38 } 39 } 40 int main() 41 { 42 ios::sync_with_stdio(false); 43 freopen("codecoder.in","r",stdin); 44 freopen("codecoder.out","w",stdout); 45 int n; 46 memset(cnt,0,sizeof(cnt)); 47 memset(visit,false,sizeof(visit)); 48 cin>>n; 49 for(int i=1;i<=n;++i){ 50 cin>>node[i].cc>>node[i].tf; 51 node[i].id=i; 52 } 53 sort(node+1,node+1+n,cmp1); 54 for(int i=1;i<n;++i) 55 g[node[i+1].id].push_back(node[i].id); 56 sort(node+1,node+1+n,cmp2); 57 for(int i=1;i<n;++i) 58 g[node[i+1].id].push_back(node[i].id); 59 for(int i=1;i<n;++i) 60 g[i].erase(unique(g[i].begin(),g[i].end()),g[i].end());//数据的去重处理,其实可要可不要。但加上肯定没有错 61 //print(n); 62 tot=0; 63 for(int i=1;i<=n;++i){ 64 if(!visit[node[i].id]) 65 dfs(node[i].id); 66 cnt[node[i].id]=tot-1; 67 } 68 for(int i=1;i<=n;++i) 69 cout<<cnt[i]<<endl; 70 return 0; 71 }