1. 程式人生 > >The Geodetic Set Problem UVA - 1198

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;
}