TTTTTTTTTTT 400D Dima and Bacteria 细菌 最短路
题意: 题目大意:给出n,m和k,表示有n个细菌,m种仪器和k种细菌,给出k种细菌的数量ci,然后每个细菌按照种类排成一排(所以有第i种细菌的序号从∑(1≤j≤i-1)cj + 1 到∑(1≤j≤i)cj);接下来给出m种仪器,有u,v,x三个值,表示说从可以在第u,v号细菌之间移动能量,代价为x。请帮助博士判断说这些细菌是否正确,正确的前提条件是说同种细菌之间移动能量为0,如果正确的话,给出两两细菌(种类)间移动能量的最小值。
AC代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #include <map> #include <algorithm> #include <set> using namespace std; typedef long long ll; typedef unsigned long long Ull; #define MM(a,b) memset(a,b,sizeof(a)); const double eps = 1e-10; const int inf = 0x3f3f3f3f; const double pi= acos (-1); const int mod=100000000; struct edge{ int to,c; }; vector<edge> G[100600]; int c[100600],f[100600],be[100600],dist[600][600],n,m,k; void add_edge( int u, int v, int c) { G[u].push_back((edge){v,c}); G[v].push_back((edge){u,c}); } int findr( int u) { if (f[u]!=u) f[u]=findr(f[u]); return f[u]; } bool legal() { for ( int i=1;i<=k;i++) { int r=findr(c[i-1]+1); for ( int j=c[i-1]+2;j<=c[i];j++) if (r!=findr(j)) return false ; } return true ; } int main() { while (~ scanf ( "%d %d %d" ,&n,&m,&k)) { for ( int i=1;i<=n;i++) {G[i].clear();f[i]=i;} for ( int i=1;i<=k;i++) { scanf ( "%d" ,&c[i]); c[i]+=c[i-1]; for ( int j=c[i-1]+1;j<=c[i];j++) be[j]=i; } MM(dist,inf); for ( int i=1;i<=m;i++) { int u,v,c; scanf ( "%d %d %d" ,&u,&v,&c); add_edge(u,v,c); if (!c) { int ru=findr(u); int rv=findr(v); if (ru!=rv) f[rv]=ru; } } if (!legal()) { printf ( "No\n" ); continue ;}; for ( int i=1;i<=n;i++) for ( int j=0;j<G[i].size();j++) { int u=i,v=G[i][j].to; if (dist[be[u]][be[v]]>G[i][j].c) dist[be[v]][be[u]]=dist[be[u]][be[v]]=G[i][j].c; } for ( int w=1;w<=k;w++) for ( int i=1;i<=k;i++) for ( int j=1;j<=k;j++) dist[i][j]=min(dist[i][j],dist[i][w]+dist[w][j]); printf ( "Yes\n" ); for ( int i=1;i<=k;i++) for ( int j=1;j<=k;j++) { if (i==j) printf ( "0 " ); else if (dist[i][j]==inf) printf ( "-1 " ); else printf ( "%d " ,dist[i][j]); if (j==k) printf ( "\n" ); } } return 0; } |
并查集+floyd
wa代码,好好查错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <stack> #include <map> #include <algorithm> #include <set> using namespace std; typedef long long ll; typedef unsigned long long Ull; #define MM(a,b) memset(a,b,sizeof(a)); const double eps = 1e-10; const int inf = 0x3f3f3f3f; const double pi= acos (-1); const int mod=100000000; struct edge{ int to,c; }; vector<edge> G[100005]; int c[100005],f[100005],n,m,k; void add_edge( int u, int v, int c) { G[u].push_back((edge){v,c}); G[v].push_back((edge){u,c}); } int findr( int u) { if (f[u]!=u) return findr(f[u]); } bool legal() { for ( int i=1;i<=k;i++) { int r=findr(c[i-1]+1); for ( int j=c[i-1]+2;j<=c[i];j++) if (r!=findr(j)) return false ; } return true ; } int main() { while (~ scanf ( "%d %d %d" ,&n,&m,&k)) { for ( int i=1;i<=n;i++) {G[i].clear();f[i]=i;} for ( int i=1;i<=k;i++) { scanf ( "%d" ,&c[i]);c[i]+=c[i-1];} for ( int i=1;i<=m;i++) { int u,v,c; scanf ( "%d %d %d" ,&u,&v,&c); add_edge(u,v,c); if (!c) { int ru=findr(u); int rv=findr(v); if (ru!=rv) f[rv]=ru; } } if (!legal()) { printf ( "No\n" ); continue ;}; } return 0; } |
你说,我们都会幸福的,对吧?
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步