CF449B Jzzhu and Cities

1522713-20191007164955824-1900898284.png

1522713-20191007165008409-1040190928.png

5 5 3
1 2 1
2 3 2
1 3 3
3 4 4
1 5 5
3 5
4 5
5 5
2
2 2 3
1 2 2
2 1 3
2 1
2 2
2 3
2

思路 :

剪完圖後,記錄一個最小邊權的個數,如果從1到v的距離有多個,那麼就可以考慮刪除v

代碼

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#define int long long
#define maxn 1100000
using namespace std ;
struct dy{
    int x , y , z , next ;
}a[maxn] ;
int head[maxn] , vis[maxn] , dis[maxn] ;
int n , m ,k  ; 
int U[maxn] , V[maxn] ,in[maxn] ;
typedef pair<int,int>pa ; 
priority_queue<pa,vector<pa>,greater<pa> >q ;
int t ;
void add(int x , int y , int z) {
    a[++t].x = x ;
    a[t].y = y ;
    a[t].z = z ;
    a[t].next = head[x] ;
    head[x] = t ;
}
void dij(int s) {
    memset(dis,0x3f,sizeof(dis)) ;
    memset(vis,0,sizeof(vis)) ;
    dis[s] = 0 , vis[s] = 0 ;
    q.push(make_pair(dis[s],s)) ;
    while(!q.empty()) {
        int u = q.top().second ;
        q.pop() ;
        if(vis[u]) continue ;
        vis[u] = 1 ;
        for(int i = head[u] ; i ; i = a[i].next ) {
            int v = a[i].y ;
            if(dis[v] > dis[u] + a[i].z ) {
                dis[v] = dis[u] + a[i].z ;
                in[v] = 1 ;
                q.push(make_pair(dis[v],v)) ;
            }else if(dis[v] == dis[u] + a[i].z) {
                in[v] ++ ;
            }
        }
    }
} 
signed main () {
    scanf("%lld%lld%lld",&n,&m,&k) ;
    while(m --) {
        int x , y , z ;
        scanf("%lld%lld%lld",&x,&y,&z) ;
        add(x,y,z) ;
        add(y,x,z) ;
    }
    for(int i = 1 ; i <= k ; i ++) {
        scanf("%lld%lld",&U[i],&V[i]) ;
        add(1,U[i],V[i]) ;
        add(U[i],1,V[i]) ;
    }
    dij(1) ;int ans = 0 ;
    for(int i = 1 ; i <= k ; i ++) {
        if(dis[U[i]] < V[i] ) ans ++ ;
        else {
            if(dis[U[i]] == V[i] && in[U[i]] > 1) ans ++ , in[U[i]] -- ;
        }
    }
    printf("%lld\n",ans) ;
    return 0 ;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章