题意:在一个带全有向图中找一点使其道其它所有点的最短距离最大的那个最小。
解法:flyod+枚举点,没觉着和DP有什么关系。
#include <stdio.h>
#define N 105
#define INF 1 << 28
int g[N][N], mark[N];
void floyd(int n)
{
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
{
if(i == k) continue;
for(int j = 1; j <= n; j++)
{
if(j == k || i == j) continue;
if(g[i][k] + g[k][j] < g[i][j])
{
g[i][j] = g[i][k] + g[k][j];
}
}
}
}
void dfs(int u, int n)
{
mark[u] = 1;
for(int i = 1; i <= n; i++)
{
if(!mark[i]) dfs(i, n);
}
}
int main()
{
int n, m, a, b, dis;
while(scanf("%d", &n), n)
{
for(int i = 1; i <= n; i++)
{
g[i][i] = mark[i] = 0;
for(int j = i + 1; j <= n; j++)
g[i][j] = g[j][i] = INF;
}
for(int i = 1; i <= n; i++)
{
scanf("%d", &m);
for(int j = 0; j < m; j++)
{
scanf("%d %d", &a, &b);
if(b < g[i][a]) g[i][a] = b;
}
}
dfs(1, n);
bool flag = 0;
for(int i = 1; i <= n; i++)
{
if(!mark[i])
{
flag = 1;
break;
}
}
if(flag)
{
printf("disjoint");
continue;
}
floyd(n);
dis = INF;
for(int i = 1; i <= n && mark; i++)
{
b = -INF;
for(int j = 1; j <= n && mark; j++)
{
if(i == j) continue;
if(g[i][j] > b) b = g[i][j];
}
if(b < dis) a = i, dis = b;
}
printf("%d %d\n", a, dis);
}
return 0;
}