P1629 邮递员送信


正着跑一边,然后反着跑的把所有边的方向调换一下就好了。在图基础上加n再方向,这样很方便!orz!!!

#include 
using namespace std;
#define forn(i,n) for(int i = 0; i < int(n); i++)
#define long long int
#define x first
#define y second
typedef pair<int,int>PII;
const int N = 200010, INF = 0x3f3f3f3f;
int h[N], e[N], ne[N], w[N], dist[N], idx;
bool st[N];
int n, m;
void add(int a, int b, int c) {
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
void dijstra(int s) {
    memset(dist, 0x3f, sizeof dist);
    memset(st, false, sizeof st);
    dist[s] = 0;
    priority_queue, greater > q;
    q.push({dist[s], s});
    while(q.size()) {
        auto t = q.front();q.pop();
        int ver = t.y;
        if(st[ver]) continue;
        st[ver]= true;
        for(int i = h[ver]; ~i;i=ne[i]){
            int j = e[i];
            if(dist[j] > dist[ver] + w[i]){
                dist[j] = dist[ver] + w[i];
                q.push({dist[j], j});
            }
        }
    }
}
signed main() {
    cin >> n >> m;
    memset(h, -1, sizeof h);
    while(m--) {
        int a, b, c;
        cin >> a >> b >> c;
        add(a,b,c);
        add(b+n,a+n,c);
    }
    int ans = 0;
    dijstra(1);
    for(int i = 2; i <= n; i++) ans+=dist[i];
    dijstra(1+n);
    for(int i = 2+n;i <= 2*n;i++) ans+=dist[i];
    cout << ans << endl;
    return 0;    
}