zoukankan      html  css  js  c++  java
  • 计蒜客 39280.Travel-二分+最短路dijkstra-二分过程中保存结果,因为二分完最后的不一定是结果 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest M.) 2019ICPC西安邀请赛现场赛重现赛

    Travel

    There are nn planets in the MOT galaxy, and each planet has a unique number from 1 sim n1n. Each planet is connected to other planets through some transmission channels. There are mm transmission channels in the galaxy. Each transmission channel connects two different planets, and each transmission channel has a length.

    The residents of the galaxy complete the interplanetary voyage by spaceship. Each spaceship has a level. The spacecraft can be upgraded several times. It can only be upgraded 11 level each time, and the cost is cc. Each upgrade will increase the transmission distance by dd and the number of transmissions channels by ee to the spacecraft. The spacecraft can only pass through channels that are shorter than or equal to its transmission distance. If the number of transmissions is exhausted, the spacecraft can no longer be used.

    Alice initially has a 00-level spacecraft with transmission distance of 00 and transmission number of 00. Alice wants to know how much it costs at least, in order to transfer from planet 11 to planet nn.

    Input

    Each test file contains a single test case. In each test file:

    The first line contains nn, mm, indicating the number of plants and the number of transmission channels

    The second line contains cc, dd, ee, representing the cost, the increased transmission distance, and the increased number of transmissions channels of each upgrade, respectively.

    Next mm lines, each line contains u,v,wu,v,w, meaning that there is a transmission channel between uu and vv with a length of ww.

    (2 le nle 10^5, n - 1 le m le 10^5,1 le u,v le n ,1 le c,d,e,w le 10^5)(2n105,n1m105,1u,vn,1c,d,e,w105)

    (The graph has no self-loop , no repeated edges , and is connected)

    Output

    Output a line for the minimum cost. Output -11 if she can't reach.

    样例输入

    5 7
    1 1 1
    1 2 1
    1 3 5
    1 4 1
    2 3 2
    2 4 5
    3 4 3
    3 5 5

    样例输出

    5

    二分+最短路。

    代码:

      1 //M-二分+最短路dijkstra-二分过程中保存结果,因为二分完最后的不一定是结果。
      2 #include<bits/stdc++.h>
      3 using namespace std;
      4 typedef long long ll;
      5 const int maxn=1e5+10;
      6 const int inf=0x3f3f3f3f;
      7 #define pii pair<int,int>
      8 #define mp make_pair
      9 #define fi first
     10 #define se second
     11 
     12 namespace IO{
     13     char buf[1<<15],*S,*T;
     14     inline char gc(){
     15         if (S==T){
     16             T=(S=buf)+fread(buf,1,1<<15,stdin);
     17             if (S==T)return EOF;
     18         }
     19         return *S++;
     20     }
     21     inline int read(){
     22         int x; bool f; char c;
     23         for(f=0;(c=gc())<'0'||c>'9';f=c=='-');
     24         for(x=c^'0';(c=gc())>='0'&&c<='9';x=(x<<3)+(x<<1)+(c^'0'));
     25         return f?-x:x;
     26     }
     27     inline long long readll(){
     28         long long x;bool f;char c;
     29         for(f=0;(c=gc())<'0'||c>'9';f=c=='-');
     30         for(x=c^'0';(c=gc())>='0'&&c<='9';x=(x<<3)+(x<<1)+(c^'0'));
     31         return f?-x:x;
     32     }
     33 }
     34 using IO::read;
     35 using IO::readll;
     36 
     37 
     38 int n,m;
     39 int c,d,e;
     40 int head[maxn<<1],cnt;
     41 int dis[maxn],pathmin,edgemin;
     42 bool vis[maxn];
     43 priority_queue<pii,vector<pii>,greater<pii> > q;
     44 
     45 struct Edge{
     46     int u,v,w;
     47 }path[maxn];
     48 
     49 struct node{
     50     int to,next,w;
     51 }edge[maxn<<1];
     52 
     53 void init()
     54 {
     55     memset(head,-1,sizeof head);
     56     memset(edge,0,sizeof edge);
     57     memset(vis,0,sizeof vis);
     58     memset(dis,inf,sizeof dis);
     59     cnt=0;
     60 }
     61 
     62 void add(int u,int v,int w)
     63 {
     64     edge[cnt].to=v;
     65     edge[cnt].w=w;
     66     edge[cnt].next=head[u];
     67     head[u]=cnt++;
     68 }
     69 
     70 void dijkstra(int s)
     71 {
     72     dis[s]=0;
     73     q.push(mp(0,s));
     74     while(!q.empty()){
     75         int u=q.top().se;q.pop();
     76         vis[u]=true;
     77         for(int i=head[u];~i;i=edge[i].next){
     78             int v=edge[i].to;
     79             int w=edge[i].w;
     80             if(dis[v]>dis[u]+w){
     81                 dis[v]=dis[u]+w;
     82                 q.push(mp(dis[v],v));
     83             }
     84         }
     85     }
     86 }
     87 
     88 void solve()
     89 {
     90     pathmin=inf;edgemin=inf;
     91     int l=1,r=1e5;
     92     while(l<=r){
     93         int mid=(l+r)>>1;
     94         init();
     95         for(int i=1;i<=m;i++){
     96             if(path[i].w<=mid){
     97                 add(path[i].u,path[i].v,1);
     98                 add(path[i].v,path[i].u,1);
     99             }
    100         }
    101         dijkstra(1);
    102         if(dis[n]<=mid){
    103             r=mid-1;
    104             if(edgemin>mid){
    105                 edgemin=mid;
    106                 pathmin=dis[n];
    107             }
    108             else if(edgemin==mid){
    109                 pathmin=min(pathmin,dis[n]);
    110             }
    111         }
    112         else{
    113             l=mid+1;
    114         }
    115     }
    116 }
    117 
    118 int main()
    119 {
    120     n=read();m=read();
    121 //    scanf("%d%d",&n,&m);
    122     c=read();d=read();e=read();
    123 //    scanf("%d%d%d",&c,&d,&e);
    124     for(int i=1;i<=m;i++){
    125         path[i].u=read();path[i].v=read();path[i].w=read();
    126 //        scanf("%d%d%d",&path[i].u,&path[i].v,&path[i].w);
    127     }
    128     solve();//路径的最大边权
    129     edgemin=edgemin/d+(edgemin%d==0? 0:1);
    130     pathmin=pathmin/e+(pathmin%e==0? 0:1); //路径条数
    131     printf("%lld
    ",1ll*max(edgemin,pathmin)*c);
    132 }
    133 */
    134 /*
    135 
    136 5 7
    137 1 1 1
    138 1 2 3
    139 1 3 4
    140 1 4 4
    141 2 3 2
    142 2 4 5
    143 3 4 1
    144 3 5 3
    145 
    146 3
    147 
    148 
    149 
    150 /*
    151 //M-HY学长的代码orz
    152 //二分+最短路spfa
    153 #include<bits/stdc++.h>
    154 #define  INF  0x3f3f3f3f
    155 using namespace std;
    156 
    157 typedef  long long   ll;
    158 const int N = 200010, mod = 1e9+7, M = 300005;
    159 
    160 ll addCost, addDist, addNum;
    161 
    162 int n, m, fa[N], head[N], tot2;
    163 pair<ll, pair<int ,int > > e1[M];
    164 struct Edge{ int to, next; ll w; } e[M];
    165 void Init() {
    166     tot2=0;
    167     memset(head, -1, sizeof(head));
    168 }
    169 void Addedge(int u, int v, ll w) {
    170     e[tot2]={v, head[u], w}; head[u]=tot2++;
    171     e[tot2]={u, head[v], w}; head[v]=tot2++;
    172 }
    173 
    174 queue<int > Q;
    175 bool inQ[N];
    176 ll dis[N];
    177 bool spfa(int mid)
    178 {
    179     memset(inQ, false, sizeof(inQ));
    180     memset(dis, INF, sizeof(dis));
    181     dis[1] = 0;
    182     Q.push(1);
    183     inQ[1] = true;
    184     ll mostDist = addDist * mid;
    185     ll mostNum = addNum * mid;
    186     while (!Q.empty())
    187     {
    188         int u = Q.front();  //cout << u << "   " << dis[u] << "   ---- 
    ";
    189         Q.pop();
    190         for (int i = head[u]; i != -1; i = e[i].next)
    191         {
    192             if (e[i].w > mostDist)
    193                 continue;
    194             if (dis[e[i].to] > dis[u] + 1)
    195             {
    196                 dis[e[i].to] = dis[u] + 1;
    197                 if (!inQ[e[i].to])
    198                 {
    199                     Q.push(e[i].to);
    200                     inQ[e[i].to] = true;
    201                 }
    202             }
    203         }
    204         inQ[u] = false;
    205     }
    206     return dis[n] != INF && dis[n] <= mostNum;
    207 }
    208 
    209 int main()
    210 {
    211     scanf("%d %d", &n, &m);
    212     scanf("%lld %lld %lld", &addCost, &addDist, &addNum);
    213     Init();
    214     for (int i = 1; i <= m; ++ i)
    215     {
    216         scanf("%d %d %lld", &e1[i].second.first, &e1[i].second.second, &e1[i].first);
    217         Addedge(e1[i].second.first, e1[i].second.second, e1[i].first);
    218     }
    219 
    220     //cout << 1111 << endl;
    221     // 二分
    222     int l = 0, r = N, mid, ans = INF;
    223     while (l <= r)
    224     {
    225         mid = (l + r) / 2;
    226         if (spfa(mid))
    227             ans = mid, r = mid -1;
    228         else
    229             l = mid + 1;
    230         //cout << l << "   " << r << "  " << ans << endl;
    231     }
    232     if (ans == INF)
    233         printf ("-1
    ");
    234     else
    235         printf ("%lld
    ", addCost * ans);
    236 
    237     return 0;
    238 }
    239 */
  • 相关阅读:
    Haproxy的安装与配置
    keepalived工作原理和配置说明
    服务器集群与负载均衡基础知识
    Linux磁盘分区与格式化
    第12章 在.NET中操作XML
    第16章 多线程
    第10章 网络编程
    第8章 流和序列化
    关于引用类型作为参数加上ref与不加ref的区别
    第3章 C#中的委托和事件
  • 原文地址:https://www.cnblogs.com/ZERO-/p/11283838.html
Copyright © 2011-2022 走看看