zoukankan      html  css  js  c++  java
  • cogs 2109. [NOIP2015] 运输计划 WD

    ★★★   输入文件:transport.in   输出文件:transport.out   简单对比
    时间限制:1 s   内存限制:256 MB

    【题目描述】


    公元 2044 年,人类进入了宇宙纪元。

    L 国有 n 个星球,还有 n-1 条双向航道,每条航道建立在两个星球之间,这 n-1 条航道连通了 L 国的所有星球。

    小 P 掌管一家物流公司,该公司有很多个运输计划,每个运输计划形如:有一艘物

    流飞船需要从 ui 号星球沿最快的宇航路径飞行到 vi 号星球去。显然,飞船驶过一条航道 是需要时间的,对于航道 j,任意飞船驶过它所花费的时间为 tj,并且任意两艘飞船之 间不会产生任何干扰。

    为了鼓励科技创新,L 国国王同意小 P 的物流公司参与 L 国的航道建设,即允许小 P 把某一条航道改造成虫洞,飞船驶过虫洞不消耗时间。

    在虫洞的建设完成前小 P 的物流公司就预接了 m 个运输计划。在虫洞建设完成后, 这 m 个运输计划会同时开始,所有飞船一起出发。当这 m 个运输计划都完成时,小 P 的 物流公司的阶段性工作就完成了。

    如果小 P 可以自由选择将哪一条航道改造成虫洞,试求出小 P 的物流公司完成阶段 性工作所需要的最短时间是多少?


    【输入格式】


    第一行包括两个正整数 n、m,表示 L 国中星球的数量及小 P 公司预接的运输计划的数量,星球从 1 到 n 编号。

    接下来 n-1 行描述航道的建设情况,其中第 i 行包含三个整数 ai, bi 和 ti,表示第i 条双向航道修建在 ai 与 bi 两个星球之间,任意飞船驶过它所花费的时间为 ti。 接下来 m 行描述运输计划的情况,其中第 j 行包含两个正整数 uj 和 vj,表示第 j 个运输计划是从 uj 号星球飞往 vj 号星球。


    【输出格式】

    共 1 行,包含 1 个整数,表示小 P 的物流公司完成阶段性工作所需要的最短时间。

    【样例输入】

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

    【样例输出】

    11

    【提示】


    所有测试数据的范围和特点如下表所示

    请注意常数因子带来的程序效率上的影响。

    15年noip的题    简单(错误)思路:spfa+path(稳稳的超时):

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cmath>
      5 #include<cstring>
      6 #include<string>
      7 #include<queue>
      8 
      9 using namespace std;
     10 const int N=300010;
     11 const int maxn=99999;
     12 
     13 int n;
     14 int m;
     15 int now=1;
     16 int dis[N];
     17 int head[N];
     18 int path[N];
     19 bool vis[N];
     20 int bian[N];
     21 int total;
     22 queue<int>q;
     23 
     24 struct node {
     25     int u,v,w,nxt;
     26     int js;
     27 }E[N];
     28 
     29 struct NODE {
     30     int start;
     31     int end;
     32     int Answer;
     33 }Ask[N];
     34 
     35 inline void Add(int u,int v,int w)
     36 {
     37     E[now].u=u;
     38     E[now].v=v;
     39     E[now].w=w;
     40     E[now].js=now;
     41     E[now].nxt=head[u];
     42     head[u]=now;
     43     now++;
     44 }
     45 
     46 inline int read()
     47 {
     48     int x=0,f=1;
     49     char c=getchar();
     50     while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); }
     51     while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     52     return x*f;
     53 }
     54 
     55 inline void JB(int ST,int EN)
     56 {
     57     int start=ST;
     58     int end=EN;
     59     
     60     while(end!=ST)
     61     {
     62         bian[path[end]]++;
     63         end=E[path[end]].u;
     64     }
     65 }
     66 
     67 inline void chu()
     68 {
     69     for(int i=1;i<=n;i++)
     70         vis[i]=0,dis[i]=maxn,path[i]=0;
     71     while(!q.empty())q.pop();
     72 }
     73 
     74 inline void spfa(int start,int end,int x)
     75 {
     76     chu();
     77     vis[start]=1;
     78     dis[start]=0;
     79     q.push(start);
     80     
     81     while(!q.empty())
     82     {
     83         int top=q.front();
     84         q.pop();
     85         vis[top]=0;
     86         
     87         for(int i=head[top];i!=-1;i=E[i].nxt)
     88         {
     89             if(dis[E[i].v]>dis[E[i].u]+E[i].w)
     90             {
     91                 dis[E[i].v]=dis[E[i].u]+E[i].w;
     92                 path[E[i].v]=E[i].js;
     93                 if(!vis[E[i].v]) q.push(E[i].v);
     94             }
     95         }
     96     }
     97     JB(start,end);
     98     Ask[x].Answer=dis[end];
     99 }
    100 
    101 inline bool cmp(NODE a,NODE b)
    102 {
    103     return a.Answer>b.Answer;
    104 }
    105 
    106 int main()
    107 {
    108     n=read();
    109     m=read();
    110     
    111     for(int i=1;i<=n;i++)
    112         head[i]=-1;
    113     
    114     for(int i=1;i<=n-1;i++)
    115     {
    116         int u,v,w;
    117         u=read();
    118         v=read();
    119         w=read();
    120         Add(u,v,w);
    121     }
    122     for(int i=1;i<=m;i++)
    123     {
    124         int start,end;
    125         Ask[i].start=read();
    126         Ask[i].end=read();
    127         spfa(Ask[i].start,Ask[i].end,i);
    128     }
    129     
    130     sort(bian+1,bian+n+1);
    131     int YJ=0;
    132     for(int i=n;i>=1;i--)
    133     {
    134         if(bian[i]==m&&E[i].w>E[YJ].w)
    135             YJ=i;
    136     }
    137     
    138     sort(Ask,Ask+m+1,cmp);
    139     printf("%d",Ask[1].Answer-E[YJ].w);
    140     
    141     return 0;
    142 }

    lca+dfs:

      1 #include<set>
      2 #include<queue>
      3 #include<vector>
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<algorithm>
      7 
      8 using namespace std;
      9 const int maxn=300005;
     10 
     11 int n,m;
     12 set<int> s1;
     13 set<int> s2;
     14 set<int>::iterator It;
     15 vector<int> G[maxn];
     16 
     17 struct Edge {
     18     int from,to,cap;
     19 };
     20 struct Heapnode {
     21     int id,len;
     22 };
     23 bool operator <(const Heapnode &a,const Heapnode &b) {
     24     return a.len<b.len;
     25 }
     26 bool operator >(const Heapnode &a,const Heapnode &b) {
     27     return a.len>b.len;
     28 }
     29 priority_queue<Heapnode> heap;
     30 struct Query {
     31     int u,v,len,lca;
     32     bool operator < (const Query& rhs) const {
     33         return len>rhs.len;
     34     }
     35 };
     36 Query Q[maxn];
     37 vector<Edge> edges;
     38 int f[maxn][20],dist[maxn],d[maxn],num[maxn];
     39 int readint() {
     40     int x=0;
     41     char ch=getchar();
     42     while(ch<'0'||ch>'9') ch=getchar();
     43     while(ch>='0'&&ch<='9') {
     44         x=x*10+ch-'0';
     45         ch=getchar();
     46     }
     47     return x;
     48 }
     49 void dfs(int u,int fa,int sum) {
     50     dist[u]=sum;
     51     d[u]=d[fa]+1;
     52     f[u][0]=fa;
     53     for(int i=1; i<20; i++)
     54         f[u][i]=f[f[u][i-1]][i-1];
     55     for(int i=0; i<G[u].size(); i++) {
     56         if(edges[G[u][i]].to!=fa) dfs(edges[G[u][i]].to,u,sum+edges[G[u][i]].cap);
     57         else num[u]=G[u][i];
     58     }
     59 }
     60 void Lca1(int &u,int &v,int cnt) {
     61     int su=u,sv=v;
     62     if(d[u]>d[v]) {
     63         u^=v;
     64         v^=u;
     65         u^=v;
     66     }
     67     int dis=d[v]-d[u];
     68     int ret=dist[v]+dist[u];
     69     for(int i=19; i>=0; i--) {
     70         if((dis>>i)&1) v=f[v][i];
     71     }
     72     for(int i=19; i>=0; i--) {
     73         if(f[u][i]!=f[v][i]) {
     74             u=f[u][i];
     75             v=f[v][i];
     76         }
     77     }
     78     if(u!=v) {
     79         u=f[u][0];
     80         v=f[v][0];
     81     }
     82     ret-=2*dist[u];
     83     Q[cnt].u=su;
     84     Q[cnt].v=sv;
     85     Q[cnt].len=ret;
     86     Q[cnt].lca=u;
     87 }
     88 void Add_Edge1(int u,int k) {
     89     if(u==Q[k].lca) return;
     90     s1.insert(num[u]);
     91     heap.push((Heapnode) {
     92         num[u],edges[num[u]].cap
     93     });
     94     Add_Edge1(edges[num[u]].to,k);
     95 }
     96 void Add_Edge(int u,int k) {
     97     if(u==Q[k].lca) return;
     98     s2.insert(num[u]);
     99     Add_Edge(edges[num[u]].to,k);
    100 }
    101 int main() {
    102     freopen("transport.in","r",stdin);
    103     freopen("transport.out","w",stdout);
    104     n=readint();
    105     m=readint();
    106     int from,to,cap;
    107     for(int i=1; i<n; i++) {
    108         from=readint();
    109         to=readint();
    110         cap=readint();
    111         edges.push_back((Edge) {
    112             from,to,cap
    113         });
    114         edges.push_back((Edge) {
    115             to,from,cap
    116         });
    117         G[from].push_back(edges.size()-2);
    118         G[to].push_back(edges.size()-1);
    119     }
    120     dfs(1,0,0);
    121     int u,v,len;
    122     for(int i=0; i<m; i++) {
    123         u=readint();
    124         v=readint();
    125         Lca1(u,v,i);
    126     }
    127     sort(Q,Q+m);
    128     int ans=0;
    129     s1.clear();
    130     s2.clear();
    131     Add_Edge1(Q[0].u,0);
    132     Add_Edge1(Q[0].v,0);
    133     ans=Q[0].len-(heap.top()).len;
    134     for(int i=1; i<m; i++) {
    135         if(ans>=Q[i].len) break;
    136         ans=Q[i].len;
    137         Add_Edge(Q[i].u,i);
    138         Add_Edge(Q[i].v,i);
    139         It=s1.begin();
    140         for(It; It!=s1.end();) {
    141             int cnt=(*It);
    142             It++;
    143             if(!s2.count(cnt)) {
    144                 s1.erase(cnt);
    145             }
    146         }
    147         s2.clear();
    148         if(s1.empty()) break;
    149         while(!s1.count(heap.top().id)) {
    150             heap.pop();
    151         }
    152         if(Q[0].len-(heap.top()).len>=ans) break;
    153         ans=Q[0].len-(heap.top()).len;
    154     }
    155     printf("%d",ans);
    156     return 0;
    157 }
  • 相关阅读:
    GC原理---垃圾收集算法
    GC原理---对象可达判断
    散列算法和哈希表结构
    桶排序
    Spring事务梳理
    AQS
    重入锁
    CAS
    研究一下phpspider
    用php写爬虫去爬数据
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/6899844.html
Copyright © 2011-2022 走看看