http://codeforces.com/gym/101061/problem/C
题意:有n个十字路口 , m条双向道路,步行道和车道,问从u到v,要使步行路程尽可能的小,如果步行路程相同,则总路程尽可能小。
解法:以步行为第一优先级,车程为第二优先级,有车道乘车则步行就赋值为0,如果有步行无车道则该车道赋值为0。
//#include<bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <string> #include <stdio.h> #include <queue> #include <stack> #include <map> #include <set> #include <string.h> #include <vector> #include <stdlib.h> using namespace std; typedef long long ll ; #define int ll #define mod 100 #define gcd(m,n) __gcd(m, n) #define rep(i , j , n) for(int i = j ; i <= n ; i++) #define red(i , n , j) for(int i = n ; i >= j ; i--) #define ME(x , y) memset(x , y , sizeof(x)) //int lcm(int a , int b){return a*b/gcd(a,b);} //ll quickpow(ll a , ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;b>>=1,a=a*a%mod;}return ans;} //int euler1(int x){int ans=x;for(int i=2;i*i<=x;i++)if(x%i==0){ans-=ans/i;while(x%i==0)x/=i;}if(x>1)ans-=ans/x;return ans;} //const int N = 1e7+9; int vis[n],prime[n],phi[N];int euler2(int n){ME(vis,true);int len=1;rep(i,2,n){if(vis[i]){prime[len++]=i,phi[i]=i-1;}for(int j=1;j<len&&prime[j]*i<=n;j++){vis[i*prime[j]]=0;if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}else{phi[i*prime[j]]=phi[i]*phi[prime[j]];}}}return len} #define INF 0x3f3f3f3f #define PI acos(-1) #define pii pair<int,int> #define fi first #define se second #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define pb push_back #define mp make_pair #define all(v) v.begin(),v.end() #define size(v) (int)(v.size()) #define cin(x) scanf("%lld" , &x); const int N = 1e5+9; const int maxn = 1e2+9; const double esp = 1e-6; int n , m ; int c[maxn][maxn] , p[maxn][maxn] , vis[maxn] , dis[maxn]; int val[maxn]; void dijkstra(int u){ rep(i , 1 , n){ dis[i] = p[u][i]; val[i] = c[u][i]; } vis[u] = 1 ; rep(i , 1 , n-1){ int pos = -1; int map = INF , mac = INF; rep(j , 1 , n){ if(!vis[j] && map > dis[j]){ map = dis[j]; mac = val[j]; pos = j ; }else if(!vis[j] && map == dis[j] && mac > val[j]){ mac = val[j]; pos = j ; } } if(pos == -1) break; vis[pos] = 1 ; rep(j , 1 , n){ if(!vis[j] && dis[j] > dis[pos] + p[pos][j]){ dis[j] = dis[pos] + p[pos][j]; val[j] = val[pos] + c[pos][j]; }else if(!vis[j] && dis[j] == dis[pos] + p[pos][j] && val[j] > val[pos] + c[pos][j]){ val[j] = val[pos] + c[pos][j]; } } } } void init(){ ME(vis , 0); fill(p[0] , p[0]+maxn*maxn , INF); fill(c[0] , c[0]+maxn*maxn , INF); } void solve(){ init(); scanf("%lld%lld" , &n , &m); rep(i , 1 , m){ int u , v , w , k ; scanf("%lld%lld%lld%lld" , &u , &v , &w ,&k); if(k == 1){ p[u][v] = p[v][u] = min(p[u][v] , w); }else{ c[u][v] = c[v][u] = min(c[u][v] , w); } } rep(i , 1 , n){ rep(j , 1 , n){ if(c[i][j] != INF){ p[i][j] = 0 ; }else if(c[i][j] == INF && p[i][j] != INF){ c[i][j] = 0 ; } } } int u , v ; scanf("%lld%lld" , &u , &v); dijkstra(u); if(dis[v] == INF && val[v] == INF) cout << -1 << endl; else cout << dis[v] << " " << dis[v]+val[v] << endl; } signed main() { int t ; cin >> t ; while(t--){ solve(); } }