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
贴一个正确性对的就是空间被卡了一下的代码吧。。。


#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<lpl> 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<ld> 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;
}

猜你喜欢

转载自www.cnblogs.com/LLppdd/p/9134853.html