3 5 1 1 1 1 4 1 4 1 1 2 2 1 3 3 1 7 1 1 1 4 1 1 2 4 1 1 3 1 3 1 1 3 3 1 4 3 1 6 1 1 1 5 1 1 5 5 1 3 1 2 5 3 2 3 3 1
-1 2 1
求出每条可能存在的边权值赋为1,分别以1,2,3为起点进行Dij,然后枚举每个点,以该点作为桥梁 联通1,2,3,当然这些联通的点经过的点越少越好,那么求出min(d1[i]+d2[i]+d3[i]) ,即为总联通的点数减1,再用n-1减去这个值就为可去掉的最大的值。
#include <stdio.h> #include <string.h> #include <algorithm> #include <math.h> #include <stack> #define lson o<<1, l, m #define rson o<<1|1, m+1, r using namespace std; typedef long long LL; const int maxn = 305; const int MAX = 0x3f3f3f3f; const int mod = 1000000007; int t, n, g[maxn][maxn]; int d[4][maxn], vis[maxn]; struct C1 { int x, y, r; }in[maxn]; int getdis(int x1, int y1, int x2, int y2) { return (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ; } void In() { scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d%d%d", &in[i].x, &in[i].y, &in[i].r); memset(g, MAX, sizeof(g)); for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) { int tmp = getdis(in[i].x, in[i].y, in[j].x, in[j].y); if( tmp <= (in[i].r + in[j].r)*(in[i].r + in[j].r) ) g[i][j] = 1; } } void DIJ(int st) { memset(d[st], MAX, sizeof(d[st])); memset(vis, 0, sizeof(vis)); d[st][st] = 0; for(int i = 0; i < n; i++) { int tmp = MAX, pos; for(int j = 0; j < n; j++) if(vis[j] == 0 && d[st][j] < tmp) { tmp = d[st][j]; pos = j; } vis[pos] = 1; for(int j = 0; j < n; j++) if(!vis[j] && d[st][j] > d[st][pos]+g[pos][j]) d[st][j] = d[st][pos]+g[pos][j]; } } int main() { scanf("%d", &t); while(t--) { In(); DIJ(0); DIJ(1); DIJ(2); int ans = MAX; for(int i = 0; i < n; i++){ if(d[0][i] != MAX && d[1][i] != MAX && d[2][i] != MAX) // 如果没有这句话,三个数加起来可能会爆int ans = min(ans, d[0][i] + d[1][i] + d[2][i]); } if(ans == MAX) printf("-1\n"); else printf("%d\n", n-1-ans); } return 0; }
HDU 3832 Earth Hour (最短路),布布扣,bubuko.com
原文:http://blog.csdn.net/u013923947/article/details/38469505