51nod 1366 貧富差距(並查集 最短路)
阿新 • • 發佈:2018-12-03
題目來源: TopCoder
基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級演算法題
一個國家有N個公民,標記為0,1,2,...,N-1,每個公民有一個存款額。已知每個公民有一些朋友,同時國家有一條規定朋友間的存款額之差不能大於d。也就是說,a和b是朋友的話,a有x元的存款,b有y元,那麼|x-y|<=d。給定d值與N個人的朋友關係,求這個國家最富有的人和最貧窮的人的存款相差最大的可能值是多少?即求貧富差距的最大值的下界。若這個值為無窮大,輸出-1.
Input
多組測試資料,第一行一個整數T,表示測試資料數量,1<=T<=5 每組測試資料有相同的結構構成。 每組資料的第一行兩個整數N,d,表示人數與朋友間存款差的最大值,其中2<=N<=50,0<=d<=1000. 接下來有一個N*N的陣列A,若A[i][j]='Y'表示i與j兩個人是朋友,否則A[i][j]='N'表示不是朋友。其中A[i][i]='N',且保證 A[i][j]=A[j][i].
Output
每組資料一行輸出,即這個國家的貧富差距最大值的下界,如果這個值為無窮大輸出-1.
Input示例
3 3 10 NYN YNY NYN 2 1 NN NN 6 1000 NNYNNN NNYNNN YYNYNN NNYNYY NNNYNN NNNYNN
Output示例
20 -1 3000
#include<iostream> #include<algorithm> #include<string.h> #include<cstdio> #define inf 0x3f3f3f3f #define ll long long using namespace std; int map[1005][1005]; int par[1005]; void init() { for(int i=1;i<=1005;i++) par[i]=i; } int find(int x) { if(x==par[x]) return x; else return par[x]=find(par[x]); } void unite(int x,int y) { x=find(x); y=find(y); if(x==y) return ; else par[x]=y; } int main() { int t; char c; cin>>t; while(t--) { init(); int n,m; cin>>n>>m; memset(map,inf,sizeof(map)); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cin>>c; if(c=='Y') { map[i][j]=1; unite(i,j); } } map[i][i]=0; } int sum=0; for(int i=1;i<=n;i++) { if(find(i)==i) sum++; } if(sum>1) cout<<"-1\n"; else { for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(map[i][j]>map[i][k]+map[k][j]) map[i][j]=map[i][k]+map[k][j]; } } } int ans=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { ans=max(map[i][j],ans); } } cout<<ans*m<<endl; } } return 0; }