寫在前面:
在窩的部落格食用口感更佳
這應該是2019csp之前寫的最後一篇題解吧
關於碼風等細節說明:
思路:詳細解析:
就是因為條件一導致我不得套板子!我要把條件一吞掉!
怎麼吞呢?我們只保留那些所有出邊所指向的點都直接或間接與終點連通的點即可
我們可以反向建圖,從終點出發跑一邊dijkstra
這樣所有距離終點為inf的就無法到達終點,刪掉它們!
(開個bool陣列flag,將它們的flag值設為1)
把出邊到距離終點是inf的點刪掉,仍然使用flag陣列可能會多刪一些點怎麼辦?
用bool陣列tmp儲存一開始的flag陣列的值,更新全部更新到flag陣列
for(int i=1;i<=n;i++)
if(dist[i]==inf)
tmp[i]=flag[i]=1;
for(int i=1;i<=m;i++)
if(tmp[v[i]]) flag[u[i]]=1;
接下來就只要在剩下的圖上愉快地跑dijkstra了
#includeusing namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
int n,m,cnt,s,t;
int hd[10005],dist[10005];
bool vis[100005],flag[100005],tmp[100005];
//vis[i]:i點是否已被確定最短路,flag[i]:i點是否被刪
int u[200005],v[200005],to[200005],nex[200005];
void add(int u,int v)
void dijkstra(int from)
int minn=inf;
for(int i=1;i<=n;i++)
}} }
}int main()
scanf("%d%d",&s,&t);
dijkstra(t);
for(int i=1;i<=n;i++)
if(dist[i]==inf)
tmp[i]=flag[i]=1;
cnt=0;
memset(vis,0,sizeof(vis));
memset(hd,0,sizeof(hd));
memset(to,0,sizeof(to));
memset(nex,0,sizeof(nex));
for(int i=1;i<=m;i++)
if(tmp[v[i]]) flag[u[i]]=1;
for(int i=1;i<=m;i++)
if(!flag[u[i]]&&!flag[v[i]])
add(u[i],v[i]);
dijkstra(s);
if(dist[t]==inf) printf("-1\n");
else printf("%d\n",dist[t]);
return 0;
}
題解 P2296 尋找道路
在有向圖 g 中,每條邊的長度均為 1 現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件 路徑上的所有點的出邊所指向的點都直接或間接與終點連通。在滿足條件 1 的情況下使路徑最短。注意 圖 gg 中可能存在重邊和自環,題目保證終點沒有出邊。請你輸出符合條件的路徑的長度。這道題...
P2296 尋找道路
洛谷 p2296 在有向圖g 中,每條邊的長度均為1 現給定起點和終點,請你在圖中找一條從起點到終點的路徑,該路徑滿足以下條件 1 路徑上的所有點的出邊所指向的點都直接或間接與終點連通。2 在滿足條件1 的情況下使路徑最短。注意 圖g 中可能存在重邊和自環,題目保證終點沒有出邊。請你輸出符合條件的路...
P2296 尋找道路
反著建圖,從點 include include include define ri register int using namespace std const int maxn 200020,inf 1310668019 int n,m,s,t,u maxn v maxn w maxn fst m...