题意:给一个有向图,求从结点1到各结点,再从各结点回到结点1的最小花费之和。
思路:
反向建边,没了。
一开始INF设成了0x3f3f3f3f,以为真的可以当无穷大用,洛谷那边WA一发才发现它表示的数量级是(10^9),在本题不够用,遂改为1e17。然后TLE,发现关了同步的cin还是不够快,遂抄了个快读函数,过了。
换到POJ这边,一模一样的题,代码复制过去交了,WA。最后把INF改为0x3f3f3f3f3f3f3f3f,过了。奇妙评测机……
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 1000000+100;
LL read() {
LL x = 0, f = 1;char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1;c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
struct node {
LL d;
int u;
bool operator < (const node& k) const {
return d > k.d;
}
};
struct Edge {
int from, to;
LL dis;
Edge(int u,int v,LL d):from(u),to(v),dis(d){}
};
int n, m,x;
int p[maxn];
vector<Edge> Edges;
vector<Edge> A_Edges;
vector<int> G[maxn];
vector<int> A_G[maxn];
bool done[maxn];
LL d[maxn];
LL A_d[maxn];
void dij(int start, int A) {
memset(done, 0, sizeof(done));
for (int i = 1; i <= n; i++){
if (A == 0) d[i] = INF;
else A_d[i] = INF;
}
if (A == 0) d[start] = 0;
else A_d[start] = 0;
priority_queue<node> Q;
Q.push(node{ 0,start });
while (!Q.empty()) {
node x = Q.top(); Q.pop();
int u = x.u;
if (done[u]) continue;
if (A == 0) {
for (int i = 0; i < G[u].size(); i++) {
Edge& e = Edges[G[u][i]];
if (d[e.to] > d[u] + e.dis) {
d[e.to] = d[u] + e.dis;
Q.push(node{ d[e.to],e.to });
}
}
}
else {
for (int i = 0; i < A_G[u].size(); i++) {
Edge& e = A_Edges[A_G[u][i]];
if (A_d[e.to] > A_d[u] + e.dis) {
A_d[e.to] = A_d[u] + e.dis;
Q.push(node{ A_d[e.to],e.to });
}
}
}
done[u] = true;
}
}
void solve(){
n = read(); m = read();
Edges.clear();
A_Edges.clear();
for (int i = 0; i <= n; i++) G[i].clear();
for (int i = 0; i <= n; i++) A_G[i].clear();
memset(done, 0, sizeof(done));
Edges.push_back(Edge(0, 0, 0));
A_Edges.push_back(Edge(0, 0, 0));
int num = 0;
for (int i = 1; i <= m; i++) {
int u, v;
LL d;
u = read();
v = read();
d = read();
Edges.push_back(Edge(u, v, d));
A_Edges.push_back(Edge(v, u, d));
G[u].push_back(++num);
A_G[v].push_back(num);
}
dij(1, 0);
dij(1, 1);
LL ans = 0;
for (int i = 2; i <= n; i++) {
if (d[i] < INF) ans += d[i];
if (A_d[i] < INF) ans += A_d[i];
}
cout << ans<<endl;
}