Time Limit: 8000MS | Memory Limit: 262144K | |
Total Submissions: 17538 | Accepted: 5721 |
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 题意:意思很简单,给一个无向图,顶点1—n,求顶点1到其他所有顶点的来回费用最小,即求顶点1到其他顶点的最小费用以及其他所有顶点到顶点1的最小费用的和。
思路:这个题给的数据是100W,如果用邻接矩阵存可能会超内存,如果用Dij可能会超时,所以就用邻接表+SPFA,建图的时候要正逆向建图,正向建图求顶点1到其他顶点的最短路,逆向建图求其他顶点到顶点1的最短路,所以两次SPFA求以顶点1为源点的最短路径的和就是最小花费。
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std; const int maxn = ;
const int INF = 0x3f3f3f3f;
typedef long long LL; struct edge
{
int to,w;
struct edge *next;
}; struct edge *map1[maxn],*map2[maxn];
int n,m;
LL ans;
LL dis[maxn];
int inque[maxn]; void SPFA(int flag)
{
queue<int>que;
while(!que.empty())
que.pop();
for(int i = ; i <= n; i++)
{
dis[i] = INF;
inque[i] = ;
} dis[] = ;
inque[] = ;
que.push();
while(!que.empty())
{
int u = que.front();
que.pop();
inque[u] = ; struct edge *tmp;
if(flag == )
tmp = map1[u];
else tmp = map2[u];
while(tmp)
{
int v = tmp->to;
int w = tmp->w;
if(dis[v] > dis[u]+w)
{
dis[v] = dis[u] + w;
if(!inque[v])
{
inque[v] = ;
que.push(v);
}
}
tmp = tmp->next;
}
}
for(int i = ; i <= n; i++)
ans += dis[i];
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int u,v,w;
struct edge *tmp1,*tmp2;
memset(map1,,sizeof(map1));
memset(map2,,sizeof(map2));
scanf("%d %d",&n,&m);
for(int i = ; i < m; i++)
{
scanf("%d %d %d",&u,&v,&w);
tmp1 = new edge;//为tmp1开辟空间;正向建图
tmp1->to = v;
tmp1->w = w;
tmp1->next = NULL;
if(map1[u] == NULL)
map1[u] = tmp1;
else
{
tmp1->next = map1[u];
map1[u] = tmp1;
} tmp2 = new edge;//为tmp2开辟空间;逆向建图
tmp2->to = u;
tmp2->w = w;
tmp2->next = NULL; if(map2[v] == NULL)
map2[v] = tmp2;
else
{
tmp2->next = map2[v];
map2[v] = tmp2;
}
}
/*for(int i = 1; i <= n; i++)//输出邻接表。
{
printf("%d: ",i);
tmp1 = map1[i];
while(tmp1)
{
printf("%d ",tmp1->to);
tmp1 = tmp1->next;
}
printf("\n");
}*/
ans = ;
SPFA();//正向寻找1顶点到其他所有顶点的最短距离
SPFA();//逆向寻找1顶点到其他所有顶点的最短距离
printf("%lld\n",ans);
}
return ;
}