(Floyd+并查集)看完没毛病,很清晰的思路,没有弯弯绕绕
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; //#define int long long const int inf = 522133279; const int maxn = 110; const int N = 2e2 + 5; const int M = 2e2+5; int dist[maxn][maxn], ma[maxn][maxn]; bool q[maxn][maxn]; int n, m; int p[M], cnt[M]; int dy[M]; int cur; //int edge[N]; struct node { int u, v, w; bool lside[N], rside[N]; }edge[N]; int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } void merge(int a, int b) { a = find(a), b = find(b); if (a != b) { p[a] = b; cnt[b] += cnt[a]; } return; } void floyd() { int ans = 0x3f3f3f3f; for (int k = 1;k <=cur;k++) for (int i = 1;i <=cur;i++) for (int j = 1;j <=cur;j++) { //此时,dist[i,j]中存储的最短路径中的点编号都小于k,节点k不在这个最短路径中。 if (i != j && i != k && j != k) //环中至少三个点,所以需要保证三个点各不相同。 ans = min(ans, dist[i][j] + ma[i][k] + ma[k][j]); //取构成的所有环中的最小权值。 dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); //k作为中转点更新最短距离。 // cout << "*****" << ans << endl; } // cout <<"&&&&" << cur << endl; printf("%d\n", ans); } signed main() { memset(dist,31, sizeof(dist)); memset(ma, 31, sizeof(ma)); scanf_s("%d", &n); for (int i = 0; i <N; i++) { p[i] = i; cnt[i] = 1; } for (int i = 1;i <= n;i++) { int x, c, ls, rs; scanf_s("%d%d%d%d", &x, &c, &ls, &rs); edge[x].u = 2 * x - 1; edge[x].v = 2 * x; edge[x].w = c; for (int j = 1;j <= ls;j++) { int k; cin >> k; edge[x].lside[k] = 1; } for (int j = 1;j <= rs;j++) { int k; cin >> k; edge[x].rside[k] = 1; } } for (int i = 1;i <= n;i++) { for (int j = 1;j <= n;j++) { if (i == j) { continue; } if (edge[i].lside[j] && edge[j].lside[i]) { merge(edge[i].u, edge[j].u); } if (edge[i].lside[j] && edge[j].rside[i]) { merge(edge[i].u, edge[j].v); } if (edge[i].rside[j] && edge[j].lside[i]) { merge(edge[i].v, edge[j].u); } if (edge[i].rside[j] && edge[j].rside[i]) { merge(edge[i].v, edge[j].v); } } } cur = 0; for (int i = 1;i <= 2 * n;i++) { if (p[i] == i) { dy[p[i]] = ++cur; // 给剩下的集合根节点重新编号 //cur++; } } /* for (int i = 1; i <= cur; i++) for (int j = 1; j <= cur; j++) if (i == j) { ma[i][j] = 0; dist[i][j] = 0; } else ma[i][j]=dist[i][j] = 0x3f3f3f3f; cout << cur << endl;*/ //cout << cur << endl; for (int i = 1;i <= n;i++) { edge[i].u = dy[find(edge[i].u)]; // 去重 edge[i].v = dy[find(edge[i].v)]; int t =edge[i].u;int g =edge[i].v; dist[t][g] = dist[g][t] = ma[t][g] = ma[g][t] = edge[i].w; // cout << t << " " << g <<" "<<dist[t][g]<<dist[g][t]<<ma[t][g]<< endl; } floyd(); //cout << cnt[find(11)] << endl; return 0; }
纯板子,欢迎交流。
07-17
544
07-18
300
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交