2417. 指挥网络

题目链接

2417. 指挥网络

在漫长的骂战过后,利特肯王国和克努斯海洋王国之间爆发了一场武装战争。

克努斯海洋王国部队的猛烈进攻使得利特肯王国的指挥网络彻底瘫痪

临时指挥网络的建立刻不容缓。

利特肯命令史努比负责该项目。

利特肯王国共有 N 个指挥部,位于平面中的 N 个节点上(编号 1N)。

其中利特肯所在的指挥总部位于节点 1

通过对战时情况的详尽研究,史努比认为,当前最关键的一点在于建立一个单向通信网络,使得利特肯的命令能够成功传达至平面中的每个节点处。

如果希望利特肯的命令能够直接从节点 A 传递到另一个节点 B,则必须沿着连接两个节点的直线段构建一条单向传输电线。

因为战争还未停止,所以并不是所有节点对之间都能建立电线。(甚至能够建立从节点 A 传递消息至节点 B 的电线,也不一定能够建立从节点 B 传递消息至节点 A 的电线)

史努比希望这项工程所需耗费的电线长度尽可能短,以便施工可以尽快完成。

输入格式

输入包含若干测试数据。

每组数据第一行包含两个整数 N,M,表示节点总数以及可在其间建立电线的节点对数。

接下来 N 行,其中第 i 行包含两个整数 xi,yi,表示节点 i 的位置坐标为 (xi,yi)

接下来 M 行,每行包含两个整数 a,b,表示可以建立一条单向电线使得命令可以从节点 a 传递至节点 b

处理至文件末尾。

输出格式

对于每个测试数据,输出结果占一行。

如果临时网络可以成功构建,则输出所需耗费电线的最小可能长度,保留两位小数。

如果不能成功构建,则输出 poor snoopy

数据范围

1N100,
1M104,
0xi,yi105,
1a,bN,ab,
每个输入最多包含 10 组测试。

输入样例:

4 6 0 6 4 6 0 0 7 20 1 2 1 3 2 3 3 4 3 1 3 2 4 3 0 0 1 0 0 1 1 2 1 3 4 1 2 3

输出样例:

31.19 poor snoopy

解题思路

朱刘算法,最小树形图

树形图:对于有向图而言,其无环,且除根外的所有点的入度都为 1

朱刘算法主要用来求解有向图的最小树形图,即总权值最小的树形图
算法流程:对于每个点都找一条权值最小的指向该点的边,如果这样的边不能构成一个环的话,则说明找到答案,结束整个算法流程,否则缩点,对于某条指向该缩点的边,其权值需要再减去其指向缩点表示的环的点的前驱边的权值,然后继续找出这样的边,直到没有环出现
证明略

  • 时间复杂度:O(nm)

代码

// Problem: 指挥网络 // Contest: AcWing // URL: https://www.acwing.com/problem/content/2419/ // Memory Limit: 64 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } typedef pair<double,double> PDD; const int N=105; const double inf=1e9; int n,m; bool g[N][N],st[N]; PDD a[N]; double d[N][N],bd[N][N]; int pre[N]; int dfn[N],low[N],scc_cnt,id[N],timestamp,stk[N],top; bool in_stk[N]; void dfs(int x) { st[x]=true; for(int i=1;i<=n;i++) if(g[x][i]&&!st[i])dfs(i); } bool check_con() { memset(st,0,sizeof st); dfs(1); for(int i=1;i<=n;i++) if(!st[i])return false; return true; } double get_dist(int x,int y) { double dx=a[x].fi-a[y].fi; double dy=a[x].se-a[y].se; return sqrt(dx*dx+dy*dy); } void tarjan(int x) { dfn[x]=low[x]=++timestamp; stk[++top]=x,in_stk[x]=true; int y=pre[x]; if(!dfn[y]) { tarjan(y); low[x]=min(low[x],low[y]); } else if(in_stk[y])low[x]=min(low[x],dfn[y]); if(low[x]==dfn[x]) { int y; scc_cnt++; do { y=stk[top--]; in_stk[y]=false; id[y]=scc_cnt; }while(y!=x); } } double work() { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(g[i][j])d[i][j]=get_dist(i,j); else d[i][j]=inf; double res=0; while(true) { for(int i=1;i<=n;i++) { pre[i]=i; for(int j=1;j<=n;j++) if(d[pre[i]][i]>d[j][i]) pre[i]=j; } memset(dfn,0,sizeof dfn); scc_cnt=timestamp=top=0; for(int i=1;i<=n;i++) if(!dfn[i])tarjan(i); if(scc_cnt==n) { for(int i=2;i<=n;i++)res+=d[pre[i]][i]; break; } for(int i=2;i<=n;i++) if(id[i]==id[pre[i]])res+=d[pre[i]][i]; for(int i=1;i<=scc_cnt;i++) for(int j=1;j<=scc_cnt;j++) bd[i][j]=inf; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(d[i][j]<inf&&id[i]!=id[j]) { int x=id[i],y=id[j]; if(id[pre[j]]==id[j]) bd[x][y]=min(bd[x][y],d[i][j]-d[pre[j]][j]); else bd[x][y]=min(bd[x][y],d[i][j]); } n=scc_cnt; memcpy(d,bd,sizeof bd); } return res; } int main() { while(~scanf("%d%d",&n,&m)) { memset(g,0,sizeof g); for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i].fi,&a[i].se); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); if(x!=y&&y!=1)g[x][y]=true; } if(!check_con())puts("poor snoopy"); else printf("%.2lf\n",work()); } return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/16951136.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示