zoukankan      html  css  js  c++  java
  • JZOJ 5771. 【NOIP2008模拟】遨游

    Description

         MWH寒假外出旅游,来到了S国。S国划分为N个省,第i个省有Ti座城市,编号分别为Ci1,Ci2,……CiTi(各省城市编号不会重复)。所有城市间有M条双向的道路连接,从任意一个城市出发,可到达一切城市,每条道路均须收费。
         此时恰逢春运期间,S国交通运输局采取了优惠措施。当一条路的路费在[L..R]区间时,可免去。同时,每个省也有优惠措施,第i个省内的每条道路路费收其Xi%,连接第i个省和第j个省的每条道路路费收其(Xi%+Xj%)/2。
    MWH想从城市s走到城市t,请求出一对L,R,确保:

    1. MWH能免费到达目的地;
    2. L≤R;
    3. L、R均为整数;
    4. L尽可能地大,R在满足L最大的前提下最小。



    注意:因每条道路由各省的交通运输局直接管辖,所以每条道路的路费必须先得到省级优惠,再得到国家级优惠。
     
     

    Input

    第一行两个整数N,M。
    接下来M行,每行三个整数,u、v、w,表示连接u、v的道路需收费w。
    接下来N行,第i+M+1行有一个整数Ti,后面Ti个整数,分别是Ci1..CiTi(所有城市编号保证按正整数顺序给出1..  Ti)。
    下一行N个整数X1..Xi。
    最后一行,两个整数,s、t。

    Output

    一行两个整数,如题,L和R。
     

    Sample Input

    3 7
    1 2 3
    5 2 8
    1 3 7
    5 4 5
    2 4 9
    3 5 10
    3 4 2
    2 1 2
    1 3
    2 4 5
    30 50 60
    1 5
     

    Sample Output

    2 6
    
    
    
     
    做法:分别二分枚举L,R咯┑( ̄Д  ̄)┍。
    代码如下:
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <cmath>
      5 #include <queue>
      6 #define M 500007
      7 #define N 200007
      8 using namespace std;
      9 struct edge
     10 {
     11     int to, next;
     12     double val;
     13 }e[N];
     14 int n, m, ls[N], x[N], y[N], t[N], start, end, tot, tma, tin = 10000007, l, r, dis[N], L, R, ans1, ans2;
     15 double z[N], cut[N];
     16 bool v[N], b[N];
     17 queue<int> q;
     18 
     19 void add(int u, int v, double w)
     20 {
     21     e[++tot].to = v;
     22     e[tot].next = ls[u];
     23     e[tot].val = w;
     24     ls[u] = tot;
     25     e[++tot].to = u;
     26     e[tot].next = ls[v];
     27     e[tot].val = w;
     28     ls[v] = tot;
     29 }
     30 
     31 void init()
     32 { 
     33     scanf("%d%d", &n, &m);
     34     for (int i = 1; i <= m; i++)
     35         scanf("%d%d%lf", &x[i], &y[i], &z[i]);
     36     for (int i = 1; i <= n; i++)
     37     {
     38         int T, u;
     39         scanf("%d", &T);
     40         for (int j = 1; j <= T; j++)
     41             scanf("%d", &u), t[u] = i;
     42     }
     43     for (int i = 1; i <= n; i++)
     44         scanf("%lf", &cut[i]), cut[i] /= 100;
     45     scanf("%d%d", &start, &end);
     46     for (int i = 1; i <= m; i++)
     47     {
     48         if (t[x[i]] != t[y[i]])
     49         {
     50             add(x[i], y[i], z[i] * ((cut[t[x[i]]] + cut[t[y[i]]]) / 2));
     51             tin = min(tin, (int)(z[i] * ((cut[t[x[i]]] + cut[t[y[i]]]) / 2)));
     52             tma = max(tma, (int)(z[i] * ((cut[t[x[i]]] + cut[t[y[i]]]) / 2)));
     53         }
     54         else
     55         {
     56             add(x[i], y[i], z[i] * cut[t[x[i]]]);
     57             tin = min(tin, (int)(z[i] * ((cut[t[x[i]]] + cut[t[y[i]]]) / 2)));
     58             tma = max(tma, (int)(z[i] * ((cut[t[x[i]]] + cut[t[y[i]]]) / 2)));
     59         }
     60     }
     61 }
     62 
     63 bool check(int judge1, int judge2)
     64 {
     65     memset(v, 0, sizeof(v));
     66     for (int i = 1; i <= tot; i++)
     67         if (e[i].val >= judge1 && e[i].val <= judge2) v[i] = 1;
     68     memset(b, 0, sizeof(b));
     69     memset(dis, 0x7f7f7f7f, sizeof(dis));
     70     dis[start] = 0;
     71     q.push(start);
     72     b[start] = 1;
     73     while (!q.empty())
     74     {
     75         int now = q.front();
     76         q.pop();
     77         for (int i = ls[now]; i; i = e[i].next)
     78         {
     79             if (!v[i])    continue;
     80             if (dis[now] + 1 >= dis[e[i].to])    continue;
     81             dis[e[i].to] = dis[now] + 1;
     82             if (b[e[i].to])    continue;
     83             q.push(e[i].to);
     84             b[e[i].to] = 1;
     85         }
     86         b[now] = 0;
     87     }
     88     if (dis[end] != 0x7f7f7f7f)    return 1;
     89     return 0;
     90 }
     91 
     92 void work()
     93 {
     94     l = tin, r = tma + 1;
     95     while (l < r)
     96     {
     97         int mid = (l + r + 1) / 2;
     98         if (check(mid, tma + 1))    l = mid;
     99         else r = mid - 1;
    100     }
    101     L = l;
    102     l = tin, r = tma + 1;
    103     while (l < r)
    104     {
    105         int mid = (l + r) / 2;
    106         if (check(L, mid))    r = mid;
    107         else l = mid + 1;
    108     }
    109     R = l;
    110     printf("%d %d", L, R);
    111 }
    112 
    113 int main()
    114 {
    115     freopen("trip.in", "r", stdin);
    116     freopen("trip.out", "w", stdout);
    117     init();
    118     work();
    119 }
    View Code
  • 相关阅读:
    img[src*="same"]{}
    a[href$=".pdf"]解释
    ::selection{}
    a[href^=""]的解释
    who are you?
    天下武功唯快不破
    登录一下好吗??
    后台登录
    实验吧—简单的登录题
    hdu 1010
  • 原文地址:https://www.cnblogs.com/traveller-ly/p/9461195.html
Copyright © 2011-2022 走看看