P4716-[模板]最小树形图
生活随笔
收集整理的這篇文章主要介紹了
P4716-[模板]最小树形图
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P4716
題目大意
給出nnn個點mmm條邊的一張有向圖,求以rrr為根的最小外向樹。
1≤n≤100,1≤m≤1041\leq n\leq 100,1\leq m\leq 10^41≤n≤100,1≤m≤104
解題思路
考慮一種貪心,對于每個點我們先選出一個連入的最小的邊權,但是這樣可能產生環。
考慮暴力將環去掉,我們枚舉所有的環,然后將環縮成一個點,之后然后每個環外的邊都減去入點所連接邊的權值(可撤銷貪心)。
然后問題規模就縮小了,不斷重復上述過程即可。
時間復雜度O(n(n+m))O(n(n+m))O(n(n+m))
code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=110; struct node{int x,y,w; }e[N*N]; int n,m,r,h[N],pre[N],v[N],id[N],ans; int main() {scanf("%d%d%d",&n,&m,&r);for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);while(1){memset(h,0x3f,sizeof(h));memset(v,0,sizeof(v));memset(id,0,sizeof(id));for(int i=1;i<=m;i++)if(e[i].x!=e[i].y&&e[i].w<h[e[i].y])h[e[i].y]=e[i].w,pre[e[i].y]=e[i].x;for(int i=1;i<=n;i++)if(i!=r&&h[i]==h[0])return puts("-1")&0;int cnt=0;for(int p=1;p<=n;p++){if(p==r)continue;int x=p;ans+=h[x];while(x!=r&&v[x]!=p&&!id[x])v[x]=p,x=pre[x];if(x!=r&&!id[x]){id[x]=++cnt;for(int y=pre[x];y!=x;y=pre[y])id[y]=cnt;}}if(cnt==0)break;for(int i=1;i<=n;i++)if(!id[i])id[i]=++cnt;for(int i=1;i<=m;i++){e[i].w-=h[e[i].y];e[i].x=id[e[i].x];e[i].y=id[e[i].y];}r=id[r];n=cnt;}printf("%d\n",ans);return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的P4716-[模板]最小树形图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Wannafly挑战赛10F-小H和遗迹
- 下一篇: 猫千草作品集君家顺序 除了君家系列还有哪