搜索训练一
Tournament
链接:https://codeforces.com/problemset/problem/27/B
题意:有n个人两两进行一次比赛,用x,y表示(x为胜利的人),一共进行n*(n-1)/2次比赛,现在少了一次比赛记录,请找出。
做法:简单图论,找出两个点的度为n-2的,然后dfs一点是否可达另外一点,如果可以就说明可以击败,不然则相反。
#pragma comment(linker, "/STACK:1024000000,1024000000") #pragma GCC optimize(2) #include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<cmath> #include<string> #include<map> #include<vector> #include<ctime> using namespace std; #define mm(a,b) memset(a,b,sizeof(a)) typedef long long ll; const int maxn = 1e5+10;; const int inf = 0x3f3f3f3f; const int mod = 1e9+7; int gcd(int a,int b) {if(b==0) return a;return gcd(b,a%b);} bool cmp(int a,int b) { return a>b; } int grap[60]; vector<int>g[60]; int vis[60]; int a,b; int dfs(int u) { vis[u]=1; if(u==b) return 1; for(int i=0;i<g[u].size();i++) { if(vis[g[u][i]]) continue; if(dfs(g[u][i])) return 1; } return 0; } int main() { int n; scanf("%d",&n); int all=(n*(n-1)/2)-1; mm(grap,0); for(int i=0;i<all;i++) { int a1,b1; scanf("%d %d",&a1,&b1); grap[a1]++;grap[b1]++; g[a1].push_back(b1); } a=0,b=0; for(int i=1;i<=n;i++) { if(grap[i]==n-2) { if(a==0) a=i; else b=i; } } if(dfs(a)) printf("%d %d\n",a,b); else printf("%d %d\n",b,a); } /* 4 4 2 4 1 2 3 2 1 3 1 */