The Geodetic Set Problem UVA - 1198
阿新 • • 發佈:2018-11-23
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; }