洛谷P2296-寻找道路【日常图论,最短路,SPFA】
生活随笔
收集整理的這篇文章主要介紹了
洛谷P2296-寻找道路【日常图论,最短路,SPFA】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
一個有向圖,要求滿足要求的最短路徑,要求為:
路徑上的所有點的出邊所指向的點都直接或間接與終點連通。
輸入1
3 2 (3個點,2條邊)
1 2 (1和2之間可以連接)
2 1
1 3 (從1到3)
輸出1
-1
輸入2
6 6
1 2
1 3
2 6
2 5
4 5
3 4
1 5
輸出2
3
解題思路
其實我們就求出滿足要求的點,然后在這些點里找最短路,還有本人這里的方法比較復雜和麻煩
代碼
#include<cstdio> using namespace std; struct woc{int next,x,y; };//日常鄰接表 woc a[200001],lt[200001]; int xx,yy,n,m,k,state[10001],ls[10001],t,head,tail,f[10001],star,over; int fls[10001]; bool ltfl[10001]; bool v[10001]; void check()//求所有可以直接或間接到終點的邊 {int t=0;int head=0;int tail=1;state[1]=over;ltfl[state[1]]=true;//初始化while (head!=tail){head++;head=(head-1)%n+1;t=fls[state[head]];//求邊while (t!=0){if (!ltfl[lt[t].y]){tail++;tail=(tail-1)%n+1;state[tail]=lt[t].y;ltfl[lt[t].y]=true;//標記}t=lt[t].next;//求下一條邊}} } bool ok(int x)//是否滿足要求 {int t=ls[x];while (t!=0){if (!ltfl[a[t].y]) return false;t=a[t].next;}return true; } int main() {scanf("%d%d",&n,&m);state[1]=1;int u=0; for (int i=1;i<=m;i++){scanf("%d",&xx);scanf("%d",&yy);a[++u].next=ls[xx];ls[xx]=u;a[u].x=xx;a[u].y=yy;//邊lt[u].next=fls[yy];fls[yy]=u;lt[u].y=xx;lt[u].x=yy;//記錄一條回去的邊} scanf("%d%d",&star,&over);for (int i=1;i<=n;i++) f[i]=2147483647;//初始化 check();//求所有可以直接或間接到終點的邊head=0;tail=1;state[1]=star;v[state[1]]=true;f[star]=0;//初始化×2while (head!=tail){head++;//出隊head=(head-1)%n+1;//循環隊列t=ls[state[head]];while (t!=0){if (f[a[t].x]+1<f[a[t].y] && ok(a[t].y))//判斷是否滿足要求{f[a[t].y]=f[a[t].x]+1;//松弛if (!v[a[t].y]){tail++;//入隊tail=(tail-1)%n+1;//循環隊列state[tail]=a[t].y;v[a[t].y]=true;}}t=a[t].next;//下一條邊}v[state[head]]=false;//解封}if (f[over]==2147483647) printf("-1");//是否有解else printf("%d\n",f[over]); }總結
以上是生活随笔為你收集整理的洛谷P2296-寻找道路【日常图论,最短路,SPFA】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏《刺客信条:黑旗》迎来 10 周年,
- 下一篇: 洛谷P1462-通往奥格玛瑞的路【日常图