Codeforces1498 E. Two Houses
作者:互联网
题目链接
思路
因为这是一张竞赛图,由题目中也可知任意一对点之间有一条有向边。
结论:入度少的点一定能走向入度多的点。
证明:对图上的强连通分量缩点,变成一个有向拓扑图。
考虑两个强连通分量A,B。假设是由A指向B,A中的一个点为a,B中的一个点为b。a的最大入度即为\(A.size()-1\),最小入度也是\(A.size()/2\),考虑b的入度,因为A指向B,那么A中所有点和b的边都是从A指向b,所以b的入度大于等于\(A.size()\)。
因此就发现是入度少的点一定能走到入度多的点。
那就只要把这些点按度数差排序查询一下即可。
代码
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 500 + 10, M = 2e4 + 10;
int k[N];
struct Node {
int x, y, val;
friend bool operator < (const Node &a, const Node &b) {
return a.val > b.val;
}
}a[N * N];
void solve() {
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &k[i]);
}
int idx = 0;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i == j) continue;
if(k[i] >= k[j]) {
a[++idx] = {i, j, k[i] - k[j]};
}
}
}
sort(a + 1, a + 1 + idx);
for(int i = 1; i <= idx; i++) {
printf("? %d %d\n", a[i].x, a[i].y);
fflush(stdout);
char s[5];
scanf("%s", s + 1);
if(s[1] == 'Y') {
printf("! %d %d\n", a[i].x, a[i].y);
return;
}
}
puts("! 0 0");
}
int main() {
// freopen("in.txt", "r", stdin);
// int t; cin >> t; while(t--)
solve();
return 0;
}
标签:Node,const,Codeforces1498,val,int,入度,Two,Houses,size 来源: https://www.cnblogs.com/ZX-GO/p/14629626.html