• poj3662


    题目大意:有n个节点p条无向边,现在可以选择其中的任意K条免费,如果必须的边多与K跳,则花费多余所需边中权值最大的一个,求最小花费多少。

    分析:最短路+二分

    我们可以二分答案mid,对于每一个mid求最短路,将最短路中大权值大于mid的边作为免费的集合,否则作为不免费的集合,验证免费集合大小是否大于K

    这里有个技巧,就是在求最短路的过程中,把大于mid的边权值变为1,小于的为0那么最后求到的d[e](e为终点)就是需要统计的集合大小

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <set>
     5 #include <algorithm>
     6 #include <map>
     7 #include <queue>
     8 #include<vector>
     9 #define maxn 1010
    10 #define maxm 1000010
    11 #define INF 0x3fffffff
    12 using namespace std;
    13 struct edge {
    14     int to,w;
    15     edge(){}
    16     edge(int _to,int _w){
    17         to=_to;w=_w;
    18     }
    19 };
    20 typedef pair<int,int> P;
    21 int V;
    22 vector<edge> G[maxn];
    23 int d[maxn];
    24 int K;
    25 int dijkstra(int s,int x){
    26     priority_queue<P,vector<P>,greater<P> >q;
    27     for(int i=0;i<V;++i)d[i]=INF;
    28     d[s]=0;
    29     q.push(P(d[s],s));
    30     while(!q.empty()){
    31         P p = q.top();
    32         q.pop();
    33         int v = p.second;
    34         if(d[v]<p.first)continue;
    35         for(int i=0;i<G[v].size();++i){
    36             edge e = G[v][i];
    37             int dd = d[v]+(e.w>=x?1:0);
    38             if(d[e.to]>dd){
    39                 d[e.to]=dd;
    40                 q.push(P(d[e.to],e.to));
    41             }
    42         }
    43     }
    44     return d[V-1];
    45 }
    46 void solve(){
    47     int l =0,r = maxm+10;
    48     while(r-l>1){
    49         int mid = (l+r)/2;
    50         if(dijkstra(0,mid)>K)l=mid;
    51         else r=mid;
    52     }
    53     int ans = l;
    54     if(l>maxm)ans=-1;
    55     printf("%d
    ",ans);
    56 }
    57 int main (){
    58     int n,m;
    59     while(scanf("%d%d%d",&n,&m,&K)!=EOF){
    60         for(int i=0;i<=n;++i)G[i].clear();
    61         V=n;
    62         int u,v,w;
    63         for(int i=0;i<m;++i){
    64             scanf("%d%d%d",&u,&v,&w);
    65             G[u-1].push_back(edge(v-1,w));
    66             G[v-1].push_back(edge(u-1,w));
    67         }
    68         solve();
    69     }
    70 }
    View Code
  • 相关阅读:
    group by 详解
    NHibernte教程(10)--关联查询
    NHibernate教程(9)一1对n关联映射
    NHibernate教程(8)--巧用组件
    NHibernate教程(7)--并发控制
    Git初步配置 ubuntu服务器 windows客户端 虚拟机
    设计模式之GOF23状态模式
    设计模式之GOF23模板模式
    设计模式之GOF23策略
    设计模式之GOF23访问者模式
  • 原文地址:https://www.cnblogs.com/shuzy/p/3812789.html
Copyright © 2020-2023  润新知