最短路

飛行路線

\(n\) 個點 \(m\) 條邊的無向連通圖,最多能夠將 \(k\) 條邊的權值賦爲 \(0\).求 \(S\)\(t\) 的最短路徑ios

solution

分層圖跑最短路,圖與圖之間的用權值爲 \(0\) 的邊鏈接,每下一層表明免費一次,只需求 \(S\)\(t+k*n\)的最短路便可c++

#include<cstdio>
#include<cctype>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#include<utility> 
#include<functional>

int Read()
{
    int x=0;char c=getchar();
    while(!isdigit(c))
    {
        c=getchar();
    }
    while(isdigit(c))
    {
        x=x*10+(c^48);
        c=getchar();
    }
    return x;
}

using std::priority_queue;
using std::pair;
using std::vector;
using std::make_pair;
using std::greater;

struct Edge
{
    int to,next,cost;
}edge[2500001];
int cnt,head[110005];

void add_edge(int u,int v,int c=0)
{
    edge[++cnt]=(Edge){v,head[u],c};
    head[u]=cnt;
}

int dis[110005];
bool vis[110005];
void Dijkstra(int s)
{
    memset(dis,0x3f,sizeof(dis));
    dis[s]=0;
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > points;
    points.push(make_pair(0,s));
    while(!points.empty())
    {
        int u=points.top().second;
        points.pop();
        if(!vis[u])
        {
            vis[u]=1;
            for(int i=head[u];i;i=edge[i].next)
            {
                int to=edge[i].to;
                if(dis[to]>dis[u]+edge[i].cost) 
                {
                    dis[to]=dis[u]+edge[i].cost;
                    points.push(make_pair(dis[to],to));
                }
            }
        }
    }
}

int main()
{
    int n=Read(),m=Read(),k=Read(),s=Read(),t=Read();
    int u,v,c;
    for(int i=0;i<m;++i)
    {
        u=Read(),v=Read(),c=Read();
        add_edge(u,v,c);
        add_edge(v,u,c);
        for(int j=1;j<=k;++j)
        {
            add_edge(u+(j-1)*n,v+j*n);
            add_edge(v+(j-1)*n,u+j*n);
            add_edge(u+j*n,v+j*n,c);
            add_edge(v+j*n,u+j*n,c);
        }
    }
  //坑人的數據===================================
    for(int i=1;i<=k;++i){
		add_edge(t+(i-1)*n,t+i*n);
	}
  //===========================================
    Dijkstra(s);
    printf("%d",dis[t+k*n]);
    return 0;
}

Telephone Lines S

在加權無向圖上求出一條從 \(1\) 號結點到 \(N\) 號結點的路徑,使路徑上第 \(K+1\) 大的邊權儘可能小。git

solution

二分求最短路,枚舉第 \(K+1\) 大的邊的長度,若是比枚舉的值大,邊權就爲 \(1\),不然爲 \(0\) ,而後跑最短路,若是最短路徑大於 \(k\) ,那就合法,繼續縮小範圍,不然擴大範圍算法

/*
work by:Ariel_
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <utility>
const int M = 2e3 + 5;
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}

using std::vector;
using std::pair;
using std::make_pair;
using std::priority_queue;
using std::greater;

int n, p, k;

struct edge{
	int v,nxt,w;
}e[M << 1];
int cnt,head[M];

void add_edge(int u,int v,int w){
   e[++cnt] = (edge){v, head[u], w};
   head[u] = cnt;
}
int dis[M];
bool vis[M];
bool dij(int s,int mid){
   memset(dis,0x3f,sizeof(dis));
   memset(vis,0,sizeof(vis));
   dis[1] = 0;
   priority_queue<pair<int,int> ,vector<pair<int, int> >,greater<pair<int ,int> > >q;
   q.push(make_pair(0, s));
   while(!q.empty()){
   	  int u = q.top().second; q.pop();
   	  if(!vis[u]){
   	  	vis[u] = 1;
   	  	for(int i = head[u]; i;i = e[i].nxt){
   	  	      int v = e[i].v;
		      if(dis[v] > dis[u] + (e[i].w > mid)){
		      	 dis[v] = dis[u] + (e[i].w > mid);
		      	 q.push(make_pair(dis[v], v));
			  }
		  }
	  }
   }
   if(dis[n] <= k) return true;
   else return false ; 
}
int main(){
   n = read(),p = read(),k = read();
   for(int i = 1, u, v, w;i <= p; i++){
   	 u = read(),v = read(),w = read();
     add_edge(u, v, w),add_edge(v, u, w);
   }
   
   int l = 0,r = 1000001,ans = 2100000000;
   while(l <= r){
   	 int mid = (l + r) >> 1;
	   if (dij(1, mid)){
		ans = mid;
		r = mid - 1;
	  }
 	 else
       l = mid + 1;
   }
   if(ans == 2100000000)printf("-1");
   else printf("%d",ans);
}

Cow Party S

\(n\) 個點 \(m\) 條邊的有向圖,求\(max(min(i~ -> ~x) + min(x ~->~ i))\);數組

solution

正反圖兩邊最短路優化

/*
work by:Ariel_
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <utility>
#include <queue>
const int M = 1e5 + 5;
const int N = 1e3 + 2;
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}
using std::vector;
using std::priority_queue;
using std::make_pair;
using std::pair;
using std::greater;
using std::max;	
	
struct edge{ 
  int v,nxt,w;
}e[M << 1];
int cnt,head[N];
void add_edge(int u,int v,int w){
	e[++cnt] = (edge){v,head[u], w};
	head[u] = cnt;
}

int dis[N],n, m, x;
bool vis[N]; 
void dij(int s){
   memset(vis,0,sizeof(vis));
   memset(dis,0x3f,sizeof(dis));
   dis[s] = 0;
   priority_queue<pair<int ,int>,vector<pair<int , int> >,greater<pair<int ,int > > >q;
   q.push(make_pair(0, s));
   while(!q.empty()){
   	 int u = q.top().second;
   	 q.pop();
   	 if(!vis[u]){
   	 	vis[u] = 1;
   	    for(int i = head[u]; i;i = e[i].nxt){
   	    	int v = e[i].v;
			if(dis[v] > dis[u] + e[i].w){
			   dis[v] = dis[u] + e[i].w;
			   q.push(make_pair(dis[v],v));
			} 
		 }	 
	 }
   }
}
int main(){
  n = read(),m = read(),x = read();
  for(int i = 1,u, v, w;i <= m; i++){
  	 u = read(),v = read(),w = read();
  	 add_edge(u, v, w);  
  }

  int tot[N];
  for(int i = 1;i <= n; i++){
  	  dij(i);
  	  tot[i] = dis[x];
  }  
  dij(x);
  int ans = 0;
  for(int i = 1;i <= n; i++){
  	 ans = max(ans,tot[i] + dis[i]);
  }
  printf("%d",ans);
}

[USACO06NOV]Roadblocks G

給一張無向圖,求這張圖的嚴格次短路之長。spa

solution

兩個 \(dis\) 數組一個存最小值,一個存次小值,維護次小值比最小值大且比其餘的邊的值小設計

/*
work by:Ariel_
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <utility>
#include <cstring>
const int M = 1e5 + 5;
const int N = 5e3 + 4;
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}
using std::queue;

int n, m;
struct edge{
   int v,nxt,w;
}e[M << 1];

int cnt,head[M];
void add_edge(int u,int v,int w){
   e[++cnt] = (edge){v, head[u], w};
   head[u] = cnt;
}
int dis1[N],opt[N],dis2[N];
bool vis[N];
void spfa(int s){
	
	memset(dis1,0x3f,sizeof(dis1));
	memset(dis2,0x3f,sizeof(dis2));
	dis1[s] = 0;
  queue <int> q;
  q.push(s);
	while(!q.empty()){
	int u = q.front();
    q.pop();vis[u] = 0;
	   for(int i = head[u]; i;i = e[i].nxt){
			int v = e[i].v;
			if(dis1[v] > dis1[u] + e[i].w){
				dis2[v] = dis1[v];
				dis1[v] = dis1[u]+e[i].w;
				if(!vis[v]) q.push(v),vis[v] = 1;
			}
			else if(dis1[u] + e[i].w < dis2[v] && dis1[u] + e[i].w > dis1[v]){
				dis2[v] = dis1[u] + e[i].w;
				if(!vis[v]) q.push(v),vis[v] = 1;
			}
			if(dis2[u] + e[i].w < dis2[v])
			{
				dis2[v] = dis2[u] + e[i].w;
				if(!vis[v]) q.push(v),vis[v] = 1;
			}
       }
	}
} 
int main(){
  n = read(),m = read();
  for(int i = 1,u,v,w;i <= m; i++){
  	  u = read(),v = read(),w = read();
  	  add_edge(u, v, w),add_edge(v, u, w);
  }
  spfa(1);
  printf("%d", dis2[n]);
}

最短路計數

給出一個 \(N\) 個頂點 \(M\) 條邊的無向無權圖,頂點編號爲 \(1 - N\) 問從頂點 \(1\) 開始,到其餘每一個點的最短路有幾條code

solution

跑最短路的時候順便計數,若是\(dis[v] > dis[u] + 1\) 就從新更新 \(ans[v]\) 的值用 \(ans[u]\) 覆蓋排序

若是\(dis[v] == dis[u] + 1\) 就直接 \(ans[v] += dis[u]\) 就行了

/*
work by:Ariel_
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
const int mod = 100003;
const int N = 1e6 + 5;
const int M = 2e6 + 5;
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}
using std::queue;
struct edge{
   int v,nxt;
}e[M << 1];
int cnt,head[N];

void add_edge(int u,int v){
    e[++cnt] = (edge){v,head[u]};
    head[u] = cnt;
}
int dis[N],ans[N];
bool vis[N];
void spfa(int x){
	memset(dis, 0x3f,sizeof(dis));
	queue <int> q;
	q.push(x);
	dis[1] = 0;
	vis[1] = 1;
	ans[1] = 1;
	while(!q.empty()){
	   int u = q.front();
	   q.pop();vis[u] = 0;
	   for(int i = head[u]; i;i = e[i].nxt){
	   	    int v = e[i].v;
		     if(dis[v] > dis[u] + 1){
		     	dis[v] = dis[u] + 1;
		     	ans[v] = ans[u];
		     	if(!vis[v]){
		     		vis[v] = 1;q.push(v);
				 }
			 }
			 else if(dis[v] == dis[u] + 1){
			 	 ans[v] += ans[u];
				 ans[v] %= mod;
			 }  
	   }
	}
}
int n,m;

int main(){
   n = read(),m = read();
   for(int i = 1,u, v;i <= m; i++){
   	  u = read(),v = read();
   	  add_edge(u,v);add_edge(v,u);
   }
   spfa(1);
   for(int i = 1;i <= n; i++){
   	 printf("%d\n",ans[i]);
   }
}

新年好

無向圖,求 \(1\)號點到其他五個點路徑和的最小值

solution

很簡單,無向圖,分別跑出每一個點的最短路,全排列暴力便可

由於 \(0x3f\) 卡了半上午……

/*
work by:Ariel_
*/
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <vector>
const int N = 5e4 + 5;
const int M = 1e5 + 5;
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}
using std::vector;
using std::pair;
using std::make_pair;
using std::greater;
using std::priority_queue;
using std::min;
using std::cout;
int a[7], n, m;
struct edge{
	int v,nxt,w;
}e[M << 1];
int head[N],cnt;
void add_edge(int u,int v,int w){
	e[++cnt] = (edge){v, head[u], w};
	head[u] = cnt;
}
int dis[N][6];
bool vis[N];
void dij(int x,int num){
	memset(vis , 0, sizeof(vis));
	for(int i = 1;i <= n; i++) dis[i][num] = 0x3f3f3f3f;
	priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
	dis[x][num] = 0;
    q.push(make_pair(0, x));
    while(!q.empty()){
       int u = q.top().second;
       q.pop();
       if(vis[u])continue;
       vis[u] = 1;
       for(int i = head[u]; i; i = e[i].nxt){
       	    int v = e[i].v;
       	   	 if(dis[v][num] > dis[u][num] + e[i].w){
       	   	   	dis[v][num] = dis[u][num] + e[i].w;
       	   	    q.push(make_pair(dis[v][num], v));
 			}
	   }
	}
}
int js,bok[7], ans = 0x3f3f3f3f;
void dfs(int x,int tot,int last){
   if(x == 5){
   	  ans = min(ans, tot);
	  return ;
   }
   for(int i = 1;i <= 5; i++){
   	     if(bok[i]) continue;
   	   	   bok[i] = 1;
   	   	   dfs(x + 1,tot + dis[a[i]][last + 1], i);
   	   	   bok[i] = 0;
   }
}
int main(){
   n = read(),m = read();
   for(int i = 1;i <= 5; i++) a[i] = read();
   
   for(int i = 1,u, v, w;i <= m; i++){
   	 u = read(),v = read(),w = read();
   	 add_edge(u, v, w),add_edge(v, u, w);
   }
   
   dij(1, 1);
   for(int i = 1;i <= 5; i++) dij(a[i], i + 1);
   dfs(0, 0, 0);
   printf("%d\n",ans);
}

最優貿易

求一條點和邊均可重複的路徑,使得路徑上存在兩點 \(a, b\) ,使得 \(a\) 先比 \(b\) 訪問且 \(Vb-Va\) 儘量地大

solution

分層圖最短路,建三層圖,在每層圖上跑表明沒有交易,若是從一層圖上了第二層圖表明買入,從第二層上到第三層表明賣出,一二層圖之間用兩點間權值鏈接,二三層圖用負權值鏈接,跑出最短路,貿易總額就是最短路的相反數

/*
work by:Ariel_
*/
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
const int N = 1e5 + 5;
const int M = 5e5 + 5; 
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}
using std::priority_queue;
using std::vector;
using std::pair;
using std::make_pair;
using std::greater;
using std::max;
struct edge{ 
   int v,nxt,w;
}e[M * 3];
int cnt,head[N * 3];
void add_edge(int u,int v,int w){
	e[++cnt] = (edge){v,head[u], w};
	head[u] = cnt;
} 
bool vis[M * 3];
int dis[M * 3];
void dij(int x){
   memset(dis, 0x3f3f3f, sizeof(dis));
   priority_queue<pair<int ,int>,vector<pair<int , int> >,greater<pair<int ,int> > > q;
   q.push(make_pair(0, x));
   dis[x] = 0;
   
   while(!q.empty()){
   	  int u = q.top().second;q.pop();
   	  for(int i = head[u];i;i = e[i].nxt){
   	  	    int v = e[i].v;
   	  	    if(dis[v] > dis[u] + e[i].w){
   	  	       dis[v] = dis[u] + e[i].w;
			   q.push(make_pair(dis[v],v));	 	
			 } 
		}
   }
}
int n,m,a[N];
int main(){
   n = read(),m = read();
   for(int i = 1;i <= n; i++) a[i] = read();
   for(int i = 1,u, v,flag;i <= m; i++){
   	   u = read(),v = read(),flag = read();
       if(flag == 1){
       	  for(int k = 0;k < 3; k++)
       	  add_edge(u + k * n , v + k * n, 0);
       	  
       	  add_edge(u, v + n, a[v]);
		  add_edge(u + n,v + n + n, -a[v]);//賣出去 
	   }
	  else{
	   	   for(int k = 0;k < 3; k++){
	   	   	 add_edge(u + k * n,v + k * n, 0);
	   	   	 add_edge(v + k * n,u + k * n, 0);
		   }
		  add_edge(u, v + n, a[v]);
		  add_edge(v, u + n, a[u]);
       	  add_edge(u + n,v + n * 2, -a[v]);
       	  add_edge(v + n,u + n * 2, -a[u]);
	   }
	   add_edge(n, 3 * n, 0);
   }
   dij(1);
   int ans = 0;
   ans = max(ans,-dis[n*3]);
   printf("%d",ans); 
}

汽車加油行駛問題

給你一個\(N*N\)的矩陣,求汽車從\((1,1)\)\((N,N)\)的最小花費,汽車行進一格須要消耗一點油,汽車油儲量爲 \(k\).

1.若汽車到達一個有加油站的點,那麼必須將油加滿爲 \(k\),花費爲 \(a\);

2.若汽車往回走,即前往的點的橫座標或者縱座標在減少,須要花費 \(b\);

3.汽車也能夠本身新建一個加油站,花費\(c\) (不包括加油費用 \(a\) )

solution

分層圖,最短路;\(k\) 的範圍很小,咱們能夠建 \(k + 1\) 層圖跑最短路,具體就是以上三種狀況

注意特殊狀況:剛好到終點,剛好沒有,此時不須要加油,因此須要打個特判

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int N = 101;
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}
int n,k,a,b,c;
int mp[N][N],dis[N][N][11];
bool vis[N][N][11];
priority_queue<pair<int,pair<int,pair<int ,int> > > >q;
void dij(){
	memset(dis, 0x3f3f3f3f, sizeof(dis));
	dis[1][1][k] = 0;
	q.push(make_pair(0,make_pair(k,make_pair(1, 1))));
	while(!q.empty()){
	  int z = q.top().second.first,x = q.top().second.second.first,y = q.top().second.second.second;q.pop();//x,y爲座標,z爲油量
		if(!vis[x][y][z]){
			vis[x][y][z] = 1;
			for(int i = 0;i < 4; i++){
				int nx =x + dx[i],ny = y + dy[i],nz = z - 1,cost = dis[x][y][z];
	   	  	     if(nx > 0&&nx <= n&&ny > 0&&ny <= n){
					if(mp[nx][ny] == 1){//強制消費
						cost += a;nz = k;
					}
				  if(!nz)//沒有油了也沒碰見加油站就建一個 
				    cost += c + a,nz = k;
				  if(i >= 2)//向後走
				    cost += b;
				   if(cost < dis[nx][ny][nz]){
				   	  dis[nx][ny][nz] = cost;
				   	  q.push(make_pair(-cost,make_pair(nz,make_pair(nx, ny))));
				   } 
			   }
			}
	   }
    }
    
    int ans = 0x3f3f3f3f;
    if(dis[n][n][k] != 0x3f3f3f3f) dis[n][n][0] = dis[n][n][k] - a - c;//走到終點剛好沒有,特判 
    for(int i = 0;i < k;i++){
    	ans = min(ans,dis[n][n][i]);
	}
	printf("%d",ans);
}
int main(){
	n = read(),k = read(),a = read(),b = read(),c = read();
	for(int i = 1;i <= n; i++){
	  for(int j = 1;j <= n; j++){
	  	  mp[i][j] = read();
	  }
	}
	dij();
}

Roads and Planes G

單元最短路,有負邊,無負環,部分雙向邊,部分無向邊(spfa會卡)

solution

1.spfa,SLF 優化: 雙向隊列

/*
work by:Ariel_
*/
#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <queue>
#include <stack>
#include<climits>
const int N = 1e5 + 5;
using std::deque;
deque <int> q;
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}
struct edge{
  int v,nxt,w;
}e[N << 1];
int cnt,head[N];
void add_edge(int u,int v,int w){
	e[++cnt] = (edge){v, head[u], w};
    head[u] = cnt;
}
int n, r, p, s, dis[N];
bool vis[N];
void spfa(int s){
	memset(dis,0x3f3f3f3f, sizeof(dis));
    dis[s] = 0;vis[s] = 1;
    q.push_back(s);
    while(!q.empty()){
       int u = q.front();q.pop_front();
       for(int i = head[u]; i; i = e[i].nxt){
       	  int v = e[i].v;
       	  if(dis[v] > dis[u] + e[i].w){
       	      dis[v] = dis[u] + e[i].w;
			  if(!vis[v]){
			  	if(!q.empty() && dis[v] >= dis[q.front()])q.push_back(v);
			  	 else q.push_front(v);
			  	 vis[v] = 1;
			  }	
		   }
	   }
	   vis[u] = 0;
	}
}
int main(){
   n = read(),r = read(),p = read(),s = read();
   for(int i = 1,u, v, w;i <= r; i++){
   	   u = read(),v = read(),w = read();
	  add_edge(u, v, w),add_edge(v, u, w);
   }
   	   
   for(int i = 1,u, v, w;i <= p; i++){
	  u = read(),v = read(),w = read(),add_edge(u, v, w);
    }
   spfa(s);
   for(int i = 1;i <= n; i++){
   	if(dis[i] != 0x3f3f3f3f)printf("%d\n",dis[i]);
   	 else printf("NO PATH\n");
   }
}

最長路

\(G\) 爲有 \(n\) 個頂點的帶權有向無環圖,\(G\) 中各頂點的編號爲 \(1\)\(n\),請設計算法,計算圖 \(G\)\(<1,n>\) 間的最長路徑。

solution

由於到達n點的值只能用從 \(1\) 出發的路徑更新,因此直接拓撲排序,求最長路便可

/*
work by:Ariel_
*/
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int M = 500500;
int read(){
   int x = 0,f = 1;char c = getchar();
   while(c < '0'||c > '9'){if(c == '-')f = -1;c = getchar();}
   while(c >= '0'&&c <= '9'){x = x*10 + c - '0';c = getchar();}
   return f*x;
}
int ru[M];
struct edge{
    int v, nxt, w;
}e[M << 1];
int cnt,head[M];
void add_edge(int u,int v,int w){
	e[++cnt] = (edge){v, head[u], w};
	head[u] = cnt;
}
int n, m,vis[M],dis[M];
void topu(){
  queue<int> q;
  for(int i = 1;i <= n; i++)
  	 if(!ru[i])q.push(i);
  dis[n] = -1;vis[1] = 1;
  while(!q.empty()){
  	 int u = q.front();
  	 q.pop();
  	 for(int i = head[u]; i;i = e[i].nxt){
  	 	  int v = e[i].v;
  	 	    ru[v]--;
  	 	 if(vis[u] == 1){
  	 	 	if(dis[v] < dis[u] + e[i].w)
  	 	        dis[v] = dis[u] + e[i].w;
  	 	        vis[v] = 1;
		  } 
		  if(!ru[v]) q.push(v);
	   }
  }
}
int main(){
   n = read(),m = read();
   for(int i = 1,u, v, w;i <= m; i++){
       u = read(),v = read(),w = read();
       ru[v]++;
       add_edge(u, v, w);
   }
   topu();
   printf("%d",dis[n]);
}
相關文章
相關標籤/搜索