bzoj1579 [Usaco2009 Feb]Revamping Trails 道路升级

1579: [Usaco2009 Feb]Revamping Trails 道路升级
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 2343 Solved: 666
[Submit][Status][Discuss]
Description
每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N; 1 <= P2_i<= N). John需要T_i (1 <= T_i <= 1,000,000)时间单位用道路i从P1_i走到P2_i或者从P2_i 走到P1_i 他想更新一些路经来减少每天花在路上的时间.具体地说,他想更新K (1 <= K <= 20)条路经,将它们所须时间减为0.帮助FJ选择哪些路经需要更新使得从1到N的时间尽量少.

Input

  • 第一行: 三个空格分开的数: N, M, 和 K * 第2..M+1行: 第i+1行有三个空格分开的数:P1_i, P2_i, 和 T_i

Output

  • 第一行: 更新最多K条路经后的最短路经长度.

Sample Input
4 4 1

1 2 10

2 4 10

1 3 1

3 4 100

Sample Output
1

HINT
K是1; 更新道路3->4使得从3到4的时间由100减少到0. 最新最短路经是1->3->4,总用时为1单位. N<=10000


本来以为是双倍经验的。。。。卡空间真的神了woc 贴一个正确性对的就是空间被卡了一下的代码吧。。。 ```c++

include<bits/stdc++.h>

using namespace std;
const int maxn = 5e5 + 5, maxm = 3e5 + 5;
struct lpl{
int to, dis;
}lin;
struct ld{
int num, dis;
bool operator < (const ld &A)const{
return A.dis < dis;
}
}qwe, lpd;
vector point[maxn];
int n, m, k, s, t;
int a[maxm], b[maxm], c[maxm], dis[maxm];
bool vis[maxn];

inline void putit()
{
int x, y; scanf("%d%d%d", &n, &m, &k); k++;
for(int i = 1; i <= m; ++i) scanf("%d%d%d", &a[i], &b[i], &c[i]);
}

inline void connect(int u, int v, int dis)
{
lin.dis = dis;
lin.to = v; point[u].push_back(lin);
}

inline void build()
{
for(int i = 1; i <= k; ++i)
for(int j = 1; j <= m; ++j){
connect(a[j] + (i - 1) * n, b[j] + (i - 1) * n, c[j]);
connect(b[j] + (i - 1) * n, a[j] + (i - 1) * n, c[j]);
}
for(int i = 1; i < k; ++i)
for(int j = 1; j <= m; ++j)
connect(a[j] + (i - 1) * n, b[j] + i * n, 0), connect(b[j] + (i - 1) * n, a[j] + i * n, 0);
for(int i = 1; i <= n; ++i)
for(int j = 1; j < k; ++j)
connect((j - 1) * n + i, j * n + i, 0);
}

inline void dijkstra()
{
s = 1, t = n * k;
priority_queue q;
memset(dis, 0x3f, sizeof(dis));
qwe.num = s, qwe.dis = 0;
q.push(qwe); dis[s] = 0;
while(!q.empty()){
qwe = q.top(); q.pop();
if(vis[qwe.num]) continue;
vis[qwe.num] = true;
for(int i = point[qwe.num].size() - 1; i >= 0; --i){
int now = point[qwe.num][i].to;
if(vis[now]) continue;
if(dis[now] > dis[qwe.num] + point[qwe.num][i].dis){
dis[now] = dis[qwe.num] + point[qwe.num][i].dis;
lpd.num = now, lpd.dis = dis[now];
q.push(lpd);
}
}
}
}

int main()
{
putit();
build();
dijkstra();
cout << dis[t];
return 0;
}

posted @ 2018-06-04 18:33  沛霖  阅读(126)  评论(0编辑  收藏  举报