P1629 邮递员送信
正着跑一边,然后反着跑的把所有边的方向调换一下就好了。在图基础上加n再方向,这样很方便!orz!!!
#includeusing 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; }