1. 程式人生 > 其它 >洛谷P6175 無向圖的最小環問題

洛谷P6175 無向圖的最小環問題

傳送門:

https://www.luogu.com.cn/problem/P6175

floyd以外無腦暴搜取得偉大勝利(部分得益於資料小

註釋小能手又雙上線了(天下苦題解不說陣列是幹什麼用的久矣

 1 #include<bits/stdc++.h>
 2 #define ff(i,s,e) for(int i=s;i<=e;i++)
 3 #define fff(i,s,e) for(int i=s;i>=e;i--)
 4 using namespace std;
 5 inline int read(){
 6     register int x=0,f=1;
 7     register char
ch=getchar(); 8 while(ch>'9'||ch<'0'){if(ch=='-') f=-1;ch=getchar();} 9 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} 10 return x*f; 11 } 12 const int M=1e3*5+2; 13 int n,m,ans=2147383647; 14 int deg[M],d[M][M],nxt[M][M];//第i個點連線的點的數量 第i和第j個點之間邊長 儲存第i個點下一個可以連線的點們
15 bool vis[M][M];//搜尋用,避免重複 16 void dfs(int st,int x,int len,int tot){//環起始點,當前點,當前環總長,當前環上點數 17 if(len>ans) return;//剪大枝 18 ff(i,1,deg[x]){//遍歷與x相連的所有點 19 if(nxt[x][i]==st&&tot>=3){//可以成環且環上點數大於等於三,更新答案 20 ans=min(ans,len+d[x][nxt[x][i]]); 21 return
; 22 } 23 if(!vis[x][nxt[x][i]]){ 24 vis[x][nxt[x][i]]=vis[nxt[x][i]][x]=1;//注意雙向標記 25 dfs(st,nxt[x][i],len+d[x][nxt[x][i]],tot+1); 26 vis[x][nxt[x][i]]=vis[nxt[x][i]][x]=0;//回溯 27 } 28 } 29 } 30 int main(){ 31 n=read();m=read(); 32 int u,v,dd; 33 ff(i,1,m){ 34 u=read();v=read();dd=read(); 35 if(d[u][v]==0) d[u][v]=d[v][u]=dd,nxt[u][++deg[u]]=v,nxt[v][++deg[v]]=u; 36 else d[u][v]=d[v][u]=min(d[u][v],dd); 37 //有判斷是因為看到樣例兩點之間多個長度,直接取最小 38 } 39 ff(i,1,n){//列舉每個點作為起點 40 if(deg[i]){//若有點與其相連,搜 41 dfs(i,i,0,1); 42 } 43 } 44 if(ans!=2147383647) printf("%d",ans); 45 else printf("No solution."); 46 return 0; 47 }