最短路,先从起点1开始求到所有点的距离和,然后建反向边,再求一次和。
heap + dijstra的时候为什么加了vis在hdu过不了...
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#define N 1000005
#define MX (ll)1e10+5
using namespace std;
typedef __int64 ll;
struct node{
ll to, nxt, cost;
}edge[N*2];
ll a[N][3];
ll head[N];
ll cnt;
ll dis[N];
//ll vis[N];
ll n, m;
struct cmp{
bool operator () (const ll a, const ll b)
{
return dis[a] > dis[b];
}
};
void init()
{
cnt = 1;
memset(head, -1, sizeof(head));
}
void addedge( ll u, ll v, ll w )
{
edge[cnt].cost = w;
edge[cnt].to = v;
edge[cnt].nxt = head[u];
head[u] = cnt++;
}
ll dij()
{
priority_queue <ll, vector<ll>, cmp > q;
for( ll i = 1; i <= n; i ++ )
{
dis[i] = MX;
}
dis[1] = 0;
//memset(vis, 0, sizeof(vis));
//vis[1] = 1;
q.push(1);
while( !q.empty() )
{
ll now = q.top();
q.pop();
//vis[now] = 1;
for ( ll i = head[now]; ~i; i = edge[i].nxt )
{
ll w = edge[i].cost;
ll v = edge[i].to;
if( dis[now] + w < dis[v] )
{
dis[v] = dis[now] + w;
q.push(v);
}
}
}
ll ans = 0;
for ( ll i = 1; i <= n; i++ )
{
ans += dis[i];
}
return ans;
}
int main()
{
int tot;
for ( scanf("%d", &tot); tot--; )
{
scanf("%I64d %I64d", &n, &m);
init();
for ( ll i = 1; i <= m; i++ )
{
scanf("%I64d %I64d %I64d", &a[i][0], &a[i][1], &a[i][2]);
addedge(a[i][0], a[i][1], a[i][2]);
}
ll ans = dij();
init();
for ( ll i = 1; i <= m; i ++ )
{
addedge(a[i][1], a[i][0], a[i][2]);
}
ans += dij();
printf("%I64d\n", ans);
}
return 0;
}
spfa:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#define N 1000005
#define MX (ll)1e10+5
using namespace std;
typedef __int64 ll;
struct node{
ll to, nxt, cost;
}edge[N*2];
ll a[N][3];
ll head[N];
ll cnt;
ll dis[N];
ll vis[N];
ll n, m;
void init()
{
cnt = 1;
memset(head, -1, sizeof(head));
}
void addedge( ll u, ll v, ll w )
{
edge[cnt].cost = w;
edge[cnt].to = v;
edge[cnt].nxt = head[u];
head[u] = cnt++;
}
void spfa()
{
memset(vis, 0, sizeof(vis));
for ( int i = 1; i <= n; i++ )
dis[i] = MX;
queue<ll> q;
while( !q.empty() )
q.pop();
vis[1] = 1;
dis[1] = 0;
q.push(1);
while( !q.empty() )
{
ll now = q.front();
q.pop();
vis[now] = 0;
for ( ll i = head[now]; ~i; i = edge[i].nxt )
{
ll to = edge[i].to;
ll cost = edge[i].cost;
if( dis[now] + cost < dis[to] )
{
dis[to] = dis[now] + cost;
if( !vis[to] )
{
vis[to] = 1;
q.push(to);
}
}
}
}
}
int main()
{
int tot;
for ( scanf("%d", &tot); tot--; )
{
scanf("%I64d %I64d", &n, &m);
init();
for ( int i = 1; i <= m; i++ )
{
scanf("%I64d %I64d %I64d", &a[i][0], &a[i][1], &a[i][2]);
addedge(a[i][0], a[i][1], a[i][2]);
}
spfa();
ll ans = 0;
for ( int i = 2; i <= n; i++ )
{
ans += dis[i];
}
init();
for ( int i = 1; i <= m; i++ )
{
addedge(a[i][1], a[i][0], a[i][2]);
}
spfa();
for ( int i = 2; i <= n; i++ )
{
ans += dis[i];
}
printf("%I64d\n", ans);
}
return 0;
}