(UVA - 208)Firetruck(路徑輸出問題,回溯+並查集/floyd演算法+dfs)
題目連結: https://vjudge.net/problem/UVA-208
題意:輸入一個n(n<=20)個節點的無向圖以及某個節點k,按照字典序從小到大順序輸出從節點1到節點k的所有路徑,要求節點不能重複。
分析:路徑輸出問題,路徑的第一個和最後一個點是固定的,可以用dfs從小到大搜尋,回溯求出所有的路徑記錄並輸出。 注意要提前判斷節點1是否可以到達節點k,不然會TLE。
提前判斷能否到達,我寫了兩種:1.並查集 2.floyd演算法
並查集當然是可以判斷的,floyd演算法可以用是因為資料n不是特別大
#include<cstdio>
#include<set>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
typedef long long LL;
const int N=25;
const int INF=0x3f3f3f3f;
int a[N][N],d[N][N];
int n,vis[N],ans,b[N];
int MAX,par[N];
#define same(x,y) Find(x)==Find(y)
void floyd()///floyd演算法求最短路徑,在此題中起判斷作用
{
for(int k=1;k<=MAX;k++)
for(int i=1;i<=MAX;i++)
for(int j=1;j<=MAX;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
}
void init()
{
for(int i=0; i<N; i++)
par[i]=i;
}
int Find(int x)
{
return par[x]==x?x:Find(par[x]);
}
void unite(int x,int y)
{
x=Find(x);
y=Find(y);
if(x!=y)
par[x]=y;
}
void dfs(int cur,int pos)///搜尋所有的可行路徑
{
if(cur==n)///可以到達點n
{
ans++;///可行方案數+1
printf("1");
for(int i=1; i<pos-1; i++)
printf(" %d",b[i]);
printf(" %d\n",n);
return ;
}
for(int i=1; i<=MAX; i++)///依次遍歷
{
if(!vis[i]&&a[cur][i]==1&&same(i,n))///same()函式起判斷作用,a[cur][i]==1代表必須有路徑,vis判重
{
b[pos]=i;
vis[i]=1;
dfs(i,pos+1);
vis[i]=0;///回溯
}
}
}
int main()
{
int cas=1;
while(~scanf("%d",&n))
{
init();
printf("CASE %d:\n",cas++);
MAX=0;////MAX記錄無向圖節點的最大編號值
mem(d,INF);
mem(a,0);
int x,y;
while(~scanf("%d%d",&x,&y)&&x&&y)
{
unite(x,y);
a[x][y]=a[y][x]=1;///=1表示聯通
MAX=max(MAX,max(x,y));
}
// floyd();
vis[1]=1;
ans=0;
dfs(1,1);///從節點1開始搜尋
printf("There are %d routes from the firestation to streetcorner %d.\n",ans,n);
}
return 0;
}
相關文章
- 求最短路徑——DFS+Floyd演算法演算法
- 最短路徑--dijkstra演算法、弗洛伊德(Floyd)演算法(帶路徑輸出)演算法
- 數獨問題(DFS+回溯)
- 拓撲排序詳解(梅開二度之dfs版按字典序輸出拓撲路徑+dfs版輸出全部拓撲路徑排序
- 面試常考演算法題之並查集問題面試演算法並查集
- 演算法——路徑問題演算法
- 關於並查集問題並查集
- 並查集系列之「路徑壓縮( path compression ) 」並查集路徑壓縮
- 用 Go 劍指 Offer 12. 矩陣中的路徑 (DFS + 回溯)Go矩陣
- 最短路徑(Floyd演算法)演算法
- n皇后問題--回溯法,以DFS的方式搜尋
- 【LeetCode回溯演算法#07】子集問題I+II,鞏固解題模板並詳解回溯演算法中的去重問題LeetCode演算法
- 並查集演算法並查集演算法
- 最短路徑之Floyd演算法演算法
- [MATLAB]最短路徑Floyd演算法Matlab演算法
- week2 kuangbin 題單 最短路問題 + 並查集問題並查集
- Floyd演算法(計算最短路徑)演算法
- 路徑問題
- 並查集(二)並查集的演算法應用案例上並查集演算法
- 最短路徑——Dijkstra演算法和Floyd演算法演算法
- 多源最短路徑演算法:Floyd演算法演算法
- 並查集題目合集並查集
- 回溯問題
- 從八皇后問題到回溯演算法演算法
- 第七章 遞迴、DFS、剪枝、回溯等問題 ------------- 7.3 題解:機器人走方格問題遞迴機器人
- 並查集在實際問題中的應用並查集
- [最短路徑問題]Dijkstra演算法(含還原具體路徑)演算法
- 使用並查集處理集合的合併和查詢問題並查集
- 簡單易懂的並查集演算法以及並查集實戰演練並查集演算法
- 專題五 並查集【Kuangbin】並查集
- 為什麼並查集路徑壓縮時不需要維護rank?並查集路徑壓縮
- 並查集到帶權並查集並查集
- 遞迴路徑問題遞迴
- 資源路徑問題
- 路徑查詢演算法應用之A*演算法演算法
- Mr. Kitayuta‘s Technology CodeForces - 505D(並查集+拓撲排序或dfs找環) 題解並查集排序
- 最短路徑——floyd演算法程式碼(c語言)演算法C語言
- 【LeetCode回溯演算法#08】遞增子序列,鞏固回溯演算法中的去重問題LeetCode演算法
- [演算法學習筆記] 並查集演算法筆記並查集