zoukankan      html  css  js  c++  java
  • 道路翻新 (Revamping Trails, USACO 2009 Feb)

    题意:给定m<=50000的1-n有联通的图,求最多可以使K<=20条边变为0的情况下的最短路是多少。。

    思路:简单的分层图最短路,对于每个点拆成K个点。。

            然后求一边最短路。。

    code:

      1 /*
      2  * Author:  Yzcstc
      3  * Created Time:  2014/11/5 19:25:47
      4  * File Name: revamp.cpp
      5  */
      6 #include<cstdio>
      7 #include<iostream>
      8 #include<cstring>
      9 #include<cstdlib>
     10 #include<cmath>
     11 #include<algorithm>
     12 #include<string>
     13 #include<map>
     14 #include<set>
     15 #include<vector>
     16 #include<queue>
     17 #include<stack>
     18 #include<ctime>
     19 #define M0(x)  memset(x, 0, sizeof(int) * (n+10))
     20 #define MP make_pair
     21 #define x first
     22 #define y second
     23 using namespace std;
     24 typedef long long ll;
     25 typedef pair<ll, int> pii;
     26 const int maxn = 1200000;
     27 struct edge{
     28     int v, w, next;     
     29 } e[maxn * 5];
     30 int last[maxn], tot;
     31 int n, k, m;
     32 
     33 void add(const int &u,const int &v, const int& w){
     34      e[tot] = (edge){v, w, last[u]}; last[u] = tot++;
     35 }
     36      
     37 void init(){
     38      int u, v, w;
     39      memset(last, -1, sizeof(int) * (n * k + 10));
     40      tot = 0;
     41      for (int i = 0; i < m; ++i){
     42           scanf("%d%d%d", &u, &v, &w);
     43           add(u, v, w); add(v, u, w);
     44           for (int i = 1; i <= k; ++i){
     45                add(u + i * n, v + i * n, w);
     46                add(v + i * n, u + i * n, w); 
     47                add(u + (i-1) * n, v + i * n, 0);
     48                add(v + (i-1) * n, u + i * n, 0);
     49           }
     50      }
     51 }
     52 
     53 ll dis[maxn];
     54 int vis[maxn];
     55 void dij(){
     56      priority_queue<pii, vector<pii>, greater<pii> > q;
     57      int nt = n * k + n;
     58      memset(vis, 0, sizeof(vis));
     59      for (int i = 1; i <= nt; ++i) dis[i] = (1LL<<50); 
     60      pii tmp(0, 1); dis[1] = 0;
     61      q.push(tmp);
     62      int u, v;
     63      while (!q.empty()){
     64           u = q.top().y;
     65           q.pop();
     66           if (vis[u]) continue;
     67           vis[u] = 1;
     68           for (int p = last[u]; ~p; p = e[p].next){
     69                v = e[p].v;
     70                if (dis[u] + e[p].w < dis[v]){
     71                     dis[v] = dis[u] + e[p].w;
     72                     tmp.x = dis[v], tmp.y = v;
     73                     q.push(tmp);         
     74                }    
     75           }            
     76      }
     77 }
     78 
     79 
     80 void solve(){
     81      dij();
     82      ll ans = 1LL<<50;
     83      for (int i = 0; i <= k; ++i)
     84         ans = min(ans, dis[n+i*n]);
     85      cout << ans << endl;
     86 }
     87 
     88 int main(){
     89     freopen("a.in", "r", stdin);
     90     freopen("a.out", "w", stdout);
     91     clock_t start, finish;
     92     start = clock();
     93     while (scanf("%d%d%d", &n, &m, &k) != EOF){
     94          init();
     95          solve();
     96     }
     97     finish = clock();
     98     double t = (double)(finish - start) / CLOCKS_PER_SEC;
     99 //    printf("time = %.6f
    ", t);
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    看懂SqlServer查询计划
    Android开发16——获取网络资源之基础应用
    Android开发15——给TextView加上滚动条
    PeekMessage、GetMessage的区别
    获取不到Repeater控件中的CheckBox选中状态
    第十九讲:动态链接库
    孙鑫VC++视频教程笔记
    CEdit 控制键盘操作
    网络编程中粘包的处理方法
    VC++编程之道读书笔记(2)
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4077273.html
Copyright © 2011-2022 走看看