熱愛工作的蒜蒜
阿新 • • 發佈:2019-02-08
只有100個點,最短路預處理所有 i 到 j 的最短路,鬆弛操作時同時更新在最短路條件下該段路經過的避雨路段數(即路長) 。
然後暴力所有區間,O(n2)判斷是否起點+該區間+到終點的路長小於 要求
p = dis[1][i] + dis[i][j] + dis[j][n] ;
q = num[1][i] + num[i][j] + num[j][n] ;
如滿足, 再判斷是否淋雨的長度更短,更新即可。
#include <bits/stdc++.h> #include <climits> using namespace std; typedef long long ll ; int n , m1 , m2 , len ; const int inf = 0x3f3f3f3f ; const int maxn = 150 ; struct edge{ int u , v ; ll w ; bool real ; }; vector<int> g[maxn] ; vector<edge> Edge ; int inq[maxn] ; ll dis[maxn][maxn] ; ll num[maxn][maxn] ; void addEdge(int u , int v , ll w , bool r){ edge temp ; temp.u = u , temp.v = v , temp.w = w ; temp.real = r ; Edge.push_back(temp) ; g[u].push_back(Edge.size() - 1 ) ; } bool spfa(int u) { int i , k ; //for(int i = 0 ; i <= n ; i ++ )dis[u][i] = inf ; memset(inq , 0 , sizeof(inq)) ; dis[u][u] = 0 , inq[u] = 1 ; queue<int> q ; q.push(u) ; while(! q.empty()) { int t = q.front() ; q.pop() ; inq[t] = 0 ; for(k = 0 ; k < g[t].size() ; k ++ ){ edge e = Edge[ g[t][k] ] ; if(dis[u][e.v] > dis[u][e.u] + e.w){ dis[u][e.v]= dis[u][e.u] + e.w ; if(e.real == true) num[u][e.v] = num[u][e.u] + 1 ; else num[u][e.v] = num[u][e.u] ; //pre[e.v] = e.u ; if(! inq[e.v]){ inq[e.v] = 1 ; q.push(e.v) ; } } } } return true ; } void work(ll & len_temp , ll & num_temp){ for(int i = 0 ; i <= n ; i ++ ) dis[i][i] = 0 ; for(int i = 1 ; i <= n ; i ++ ) spfa(i) ; int temp = dis[1][n] ; if(temp > len) { num_temp = -1 ; return ; } len_temp = temp ; num_temp = num[1][n] ; int p , q ; for(int i = 1 ; i <= n ; i ++ ){ for(int j = i + 1 ; j <= n ; j ++ ){ p = dis[1][i] + dis[i][j] + dis[j][n] ; q = num[1][i] + num[i][j] + num[j][n] ; if(p <= len){ if(p - q < len_temp - num_temp){ num_temp = q ; len_temp = p ; } } } } //return num_temp ; } int main(){ int T ; scanf("%d" , &T) ; int u , v ; ll w; while( T -- ){ scanf("%d %d %d %d" , &n , &m1 , &m2 , &len) ; for(int i = 0 ; i <= n ; i ++ ) g[i].clear() ; Edge.clear() ; memset(dis , inf , sizeof(dis)) ; memset(num , 0 , sizeof(num)) ; for(int i = 0 ; i < m1 ; i ++ ){ scanf("%d %d" , &u , &v) ; addEdge(u , v , 1 , 1 ) ; addEdge(v , u , 1 , 1 ) ; } for(int i = 0 ; i < m2 ; i ++ ){ scanf("%d %d %lld" , &u , &v , &w) ; addEdge(u , v , w , 0 ) ; addEdge(v , u , w , 0 ) ; } ll num_temp = 0 , len_temp = 0 ; work(len_temp , num_temp) ; printf("%lld\n" , num_temp == -1 ? -1 : len_temp - num_temp ) ; } return 0 ; }