大意:求最短路径
思路:逆向思考,建一次反向图。
今天实现了下Dijkstra + heap,spfa+邻接表大概要2030ms左右,而Dijkstra + heap要2350左右。
还有以后如果题目给出了最大的数据的话最好别用0xfffffff等,直接用它给定的,这里我WA了好多次。
CODE:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 1000010;
const int MAXM = 1000010;
const int INF = 1000000010; //特别要注意
int n, m, cnt;
int first[MAXN];
__int64 d[MAXN];
__int64 w[MAXM];
int u[MAXM], v[MAXM], next[MAXM];
int su[MAXM], sv[MAXM];
__int64 sw[MAXM];
void init()
{
cnt = 0;
memset(u, 0, sizeof(u));
memset(v, 0, sizeof(v));
memset(w, INF, sizeof(w));
memset(next, 0, sizeof(next));
memset(d, 0, sizeof(d));
memset(first, -1, sizeof(first));
}
void read_graph(int u1, int v1, int w1)
{
v[cnt] = v1, w[cnt] = w1;
next[cnt] = first[u1], first[u1] = cnt++;
}
typedef pair<__int64,int> pii;
priority_queue<pii, vector<pii>, greater<pii> > q;
void Dijkstra(int src)
{
bool done[MAXN] = {0};
for(int i = 1; i <= n; i++) d[i] = (i == src)? 0:INF;
q.push(make_pair(d[src], src));
while(!q.empty())
{
pii u = q.top(); q.pop();
int x = u.second;
if(done[x]) continue;
done[x] = 1;
for(int e = first[x]; e != -1; e = next[e]) if(d[v[e]] > d[x]+w[e])
{
d[v[e]] = d[x] + w[e];
q.push(make_pair(d[v[e]], v[e]));
}
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
init();
__int64 tot = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
{
int u1, v1;
__int64 w1;
scanf("%d%d%I64d", &u1, &v1, &w1);
su[i] = u1, sv[i] = v1, sw[i] = w1;
read_graph(u1, v1, w1);
}
Dijkstra(1);
for(int i = 1; i <= n; i++) tot += d[i];
init();
for(int i = 1; i <= m; i++)
{
read_graph(sv[i], su[i], sw[i]);
}
Dijkstra(1);
for(int i = 1; i <= n; i++) tot += d[i];
printf("%I64d\n", tot);
}
}
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 1000010;
const int MAXM = 1000010;
const int INF = 1000000010; //特别要注意
int n, m, cnt;
int first[MAXN];
__int64 d[MAXN];
__int64 w[MAXM];
int u[MAXM], v[MAXM], next[MAXM];
int su[MAXM], sv[MAXM];
__int64 sw[MAXM];
void init()
{
cnt = 0;
memset(u, 0, sizeof(u));
memset(v, 0, sizeof(v));
memset(w, INF, sizeof(w));
memset(next, 0, sizeof(next));
memset(d, 0, sizeof(d));
memset(first, -1, sizeof(first));
}
void read_graph(int u1, int v1, int w1)
{
v[cnt] = v1, w[cnt] = w1;
next[cnt] = first[u1], first[u1] = cnt++;
}
typedef pair<__int64,int> pii;
priority_queue<pii, vector<pii>, greater<pii> > q;
void Dijkstra(int src)
{
bool done[MAXN] = {0};
for(int i = 1; i <= n; i++) d[i] = (i == src)? 0:INF;
q.push(make_pair(d[src], src));
while(!q.empty())
{
pii u = q.top(); q.pop();
int x = u.second;
if(done[x]) continue;
done[x] = 1;
for(int e = first[x]; e != -1; e = next[e]) if(d[v[e]] > d[x]+w[e])
{
d[v[e]] = d[x] + w[e];
q.push(make_pair(d[v[e]], v[e]));
}
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
init();
__int64 tot = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
{
int u1, v1;
__int64 w1;
scanf("%d%d%I64d", &u1, &v1, &w1);
su[i] = u1, sv[i] = v1, sw[i] = w1;
read_graph(u1, v1, w1);
}
Dijkstra(1);
for(int i = 1; i <= n; i++) tot += d[i];
init();
for(int i = 1; i <= m; i++)
{
read_graph(sv[i], su[i], sw[i]);
}
Dijkstra(1);
for(int i = 1; i <= n; i++) tot += d[i];
printf("%I64d\n", tot);
}
}