E. Two Houses 思维题 + 交互

E. Two Houses 思维题 + 交互

题目大意:

给你一张有向完全图,注意是完全图,也就是说,任意两个点有一条有向边。

给定每一个点的入度,问你能否找到一对 \((a,b)\) 满足有一条从 \(a\)\(b\) 的路径,也有一条从 \(b\)\(a\) 的路径,如果存在,请输入入度差最大的一对,输出 ! a b,如果不存在输出 ! 0 0

你可以进行询问 :\(?\,\,a\,\,b\) 表示,是否存在一条路径从 \(a\)\(b\)

如果存在,则输出 \(YES\) ,不存在则输出 \(NO\)

你可以进行无数次的询问,直到输出 \(YES\)

题解:

首先它是一个有向完全图,如果 \((a,b)\) 询问为 YES,那么进行分析:

  • 对于 \(a\) 来说入度为 \(k_a\) ,说明有 \(k_a\) 个点可以到达 \(a\) ,同时也可以说明 \(a\) 可以到达 \(n - 1 - k_a\) 个点
  • 对于 \(b\) 来说入度为 \(k_b\) ,说明有 \(k_b\) 个点可以到达 \(b\) ,同时说明 \(b\) 可以到达 \(n-1-k_b\)
  • 现在已知 \(a\)\(b\) 存在一条路径,那么接下来只要判断是否 \(b\)\(a\) 也存在一条路径即可。
  • 因为到达 \(a\) 的有 \(k_a\) 个点,\(b\) 到达的有 \(n-1-k_b\) 个点,如果到达 \(a\)\(b\) 到达的点有重合,则说明 \(b\) 可以到达 \(a\)
  • 那么只要满足等式 \(k_a + n-1-k_b>n-2\) 即可
  • 也就是 \(k_a>k_b-1\) ,也就是 \(k_a>=k_b\)
  • 得到这个证明之后就很简单了,直接暴力枚举即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 5e2 + 10;
const int mod = 1e9 + 7;
struct node{
    int u,v,d;
}e[maxn*maxn];
int in[maxn];
bool cmp(node a,node b){
    return a.d>b.d;
}
char s[maxn];
bool ask(int u,int v){
    printf("? %d %d\n",u,v);
    fflush(stdout);
    scanf("%s",s);
    if(s[0]=='Y') return true;
    return false;
}
int main(){
    int n,now = 0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&in[i]);
    for(int i=1;i<=n;i++) {
        for (int j = i + 1; j <= n; j++) {
            int u = i, v = j;
            if (in[u] < in[v]) swap(u, v);
            e[++now] = {u, v, in[u] - in[v]};
        }
    }
    sort(e+1,e+1+now,cmp);
    for(int i=1;i<=now;i++){
        auto u = e[i].u;
        auto v = e[i].v;
        if(ask(u,v)){
            printf("! %d %d\n",u,v);
            fflush(stdout);
            return 0;
        }
    }
    printf("! 0 0\n");
    fflush(stdout);
    return 0;
}
posted @ 2021-04-01 23:24  EchoZQN  阅读(63)  评论(0编辑  收藏  举报