Time Limit: 8000MS | Memory Limit: 262144K | |
Total Submissions: 26478 | Accepted: 8790 |
Description
The transport system is very special: all lines are unidirectional and connect exactly two stops. Buses leave the originating stop with passangers each half an hour. After reaching the destination stop they return empty to the originating stop, where they wait until the next full half an hour, e.g. X:00 or X:30, where 'X' denotes the hour. The fee for transport between two stops is given by special tables and is payable on the spot. The lines are planned in such a way, that each round trip (i.e. a journey starting and finishing at the same stop) passes through a Central Checkpoint Stop (CCS) where each passenger has to pass a thorough check including body scan.
All the ACM student members leave the CCS each morning. Each volunteer is to move to one predetermined stop to invite passengers. There are as many volunteers as stops. At the end of the day, all students travel back to CCS. You are to write a computer program that helps ACM to minimize the amount of money to pay every day for the transport of their employees.
Input
Output
Sample Input
2 2 2 1 2 13 2 1 33 4 6 1 2 10 2 1 60 1 3 20 3 4 10 2 4 5 4 1 50
Sample Output
46 210
Source
edge[i].to表示第i条边的终点,edge[i].next表示与第i条边同起点的下一条边的存储位置,edge[i].w为边权值.
另外还有一个数组head[],它是用来表示以i为起点的第一条边存储的位置,实际上你会发现这里的第一条边存储的位置其实
在以i为起点的所有边的最后输入的那个编号.
head[]数组一般初始化为-1,对于加边的add函数是这样的:
#include <cstdio>
#include <iostream>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
const int MAXN = 1000005;
const int inf = 0x3f3f3f3f;
typedef long long LL;
int head[2][MAXN];
bool vis[MAXN];
LL dist[MAXN];
struct node{
int to, next, w;
} edge[2][MAXN];
int n, m;
void spfa(int cur)
{
int v, i, b;//v为以v编号为起点
queue <int> q;
for(int i = 1; i<=n; ++i)
{
vis[i] = false;
dist[i] = inf;
}
while(!q.empty())
q.pop();
q.push(1);
vis[1] = 1;
dist[1] = 0;
while(!q.empty())
{
v = q.front();
q.pop();
vis[v] = 0;
for(i = head[cur][v]; ~i; i=edge[cur][i].next)//head[cur][v]就是v为起点的对应第几条边,若不为-1则存在到其他点的路径
{
//这里的i是以v为起点,边的编号
b = edge[cur][i].to;//从编号最大的终点开始,初始化时的i和head【a】=i中的i相等。
if(dist[b]>dist[v] + edge[cur][i].w)//以起点为v初始化时的,终点为i
{
dist[b] = dist[v] + edge[cur][i].w;
if(!vis[b])
{
vis[b] = true;
q.push(b);
}
}
}
}
}
int main()
{
int t;
int a, b, w;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &m);
for(int i = 1; i<=n; ++i)
{
head[0][i] = -1;
head[1][i] = -1;
}
for(int i = 0; i<m; ++i)
{
scanf("%d %d %d", &a, &b, &w);
edge[0][i].w = w;
edge[0][i].to = b;
edge[0][i].next = head[0][a];
head[0][a] = i;
edge[1][i].w = w;
edge[1][i].to = a;
edge[1][i].next = head[1][b];
head[1][b] = i;
}
LL ans = 0;
spfa(0);
for(int i = 1; i<=n; ++i) ans += dist[i];
spfa(1);
for(int i = 1; i<=n; ++i) ans += dist[i];
printf("%lld\n", ans);
}
return 0;
}