您的位置:首页 > 其它

51nod oj 1366 贫富差距【枚举+最长的短路】

2016-09-15 17:36 375 查看
1366 贫富差距


题目来源: 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


开始用树的直径,不出意外的WA了;

此题的联通路不是一个树---

如图:



如果按照树的直径的做法---第一次可能搜到B点--从B点再开始搜答案为1

毫无疑问:答案为2----

即:树的直径只适用于树上--------

最多50个点----

枚举最富的点====然后求最长的短路----

时间复杂度:O(n^3)

代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int n,d;
char map[1010][1010];
int fer[1010];
struct node{
int hao,step;
}now,qian;
int find(int xx)
{
if (xx==fer[xx])
return xx;
return fer[xx]=find(fer[xx]);
}
bool fafe[1010];
int dfs(int xx)
{
memset(fafe,true,sizeof(fafe));
fafe[xx]=false;
now.hao=xx;
now.step=0;
queue<node> que;
que.push(now);
int lp,yy;
while (!que.empty())
{
now=que.front();
que.pop();
lp=now.hao;
yy=now.step;
for (int i=0;i<n;i++)
{
if (map[lp][i]=='Y'&&fafe[i])
{
fafe[i]=false;
qian.hao=i;
qian.step=now.step+1;
que.push(qian);
}
}
}
return yy;
}
int main()
{
int t;scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&d);
for (int i=0;i<n;i++)
{
scanf("%s",map[i]);
fer[i]=i;
}
for (int i=0;i<n;i++)
for (int j=i+1;j<n;j++)
if (map[i][j]=='Y')
fer[find(i)]=find(j);
int s=0;
for (int i=0;i<n;i++)
if (fer[i]==i)
s++;
if (s>1)
{
printf("-1\n");
continue;
}
int p,ans=0;
for (int i=0;i<n;i++)
{
int p=dfs(i);
ans=max(p,ans);
}
printf("%d\n",d*ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: