The Geodetic Set Problem UVA - 1198

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3639

每次询问给一个点集 问这些点集中两两之间的最短路能否覆盖整个图所有点 如果两点之间有好几条最短路就都算上 且最短路的起点终点也算上

先floyd预处理 然后枚举任意两点之间的转折点 如果e[i][j]==e[i][k]+e[k][j]成立 则说明k在i和j的最短路上 这里就是是这个题的重点

因为不超过40个点 直接状压一下即可

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define pb push_back
typedef long long ll;
const int N=0x3f3f3f3f;
const int maxn=50;

vector <int> gou;
ll pre[maxn],mat[maxn][maxn];
int e[maxn][maxn];
int n,q;

void init()
{
    int i;
    pre[0]=1;
    for(i=1;i<=40;i++) pre[i]=2ll*pre[i-1];
}

void floyd()
{
    int i,j,k;
    for(k=1;k<=n;k++){
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                e[i][j]=min(e[i][j],e[i][k]+e[k][j]);
            }
        }
    }
    memset(mat,0,sizeof(mat));
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            for(k=1;k<=n;k++){//
                if(e[i][j]==e[i][k]+e[k][j]){
                    mat[i][j]|=pre[k-1];
                }
            }
        }
    }
}

int main()
{
    ll ans;
    int i,j;
    char ch;
    init();
    while(scanf("%d",&n)!=EOF){
        for(i=1;i<=n;i++){
            for(j=1;j<=n;j++){
                if(i==j) e[i][j]=0;
                else e[i][j]=-N;
            }
        }
        for(i=1;i<=n;i++){
            while(1){
                scanf("%d",&j);
                e[i][j]=1;
                ch=getchar();
                if(ch=='\n') break;
            }
        }
        floyd();
        scanf("%d",&q);
        while(q--){
            gou.clear();
            while(1){
                scanf("%d",&j);
                gou.pb(j);
                ch=getchar();
                if(ch=='\n') break;
            }
            ans=0;
            for(i=0;i<gou.size();i++){
                for(j=0;j<gou.size();j++){
                    if(i!=j) ans|=mat[gou[i]][gou[j]];
                }
            }
            if(ans==pre[n]-1) printf("yes\n");
            else printf("no\n");
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/84104822