zoukankan      html  css  js  c++  java
  • poj

    http://poj.org/problem?id=3268

    每头牛都要去标号为X的农场参加一个party,农场总共有N个(标号为1-n),总共有M单向路联通,每头牛参加完party之后需要返回自己的农场,但是他们都想选一条最近的路,并且由于路是单向的,去的路和来的路选择可能不一样,问来去时间之和最大是多少?

    这题等于给定了起点和终点,那么求出(d[x][i]+d[i][x])最大的那个即可。

    开始错了几次,太不小心了,就是最后求最大值的时候,用了一个临时变量没置0,所以可能会导致错误。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <set>
     8 #include <map>
     9 #include <string>
    10 #include <cmath>
    11 #include <cstdlib>
    12 #include <ctime>
    13 using namespace std;
    14 const int maxn= 1010;
    15 const int INF = 1<<29;
    16 struct edge{
    17     int to,cost;
    18     edge(){}
    19     edge(int x,int y) {
    20         to=x;
    21         cost=y;
    22     }
    23 };
    24 typedef pair<int,int>P;
    25 
    26 int N,M,X;
    27 vector<edge>G[maxn];
    28 int d[maxn];
    29 
    30 int dijkstra(int s,int t) {
    31     priority_queue<P,vector<P>,greater<P> >que;
    32     for(int i=0;i<=N;i++) d[i]=INF;
    33     d[s]=0;
    34     que.push(P(0,s));
    35 
    36     while(!que.empty()) {
    37         P p=que.top(); que.pop();
    38         int v=p.second;
    39         if(v==t) return d[t];
    40         if(d[v]<p.first) continue;
    41         for(int i=0;i<G[v].size();i++) {
    42             edge e=G[v][i];
    43             if(d[e.to]>d[v]+e.cost) {
    44                 d[e.to]=d[v]+e.cost;
    45                 que.push(P(d[e.to],e.to));
    46             }
    47         }
    48     }
    49 }
    50 
    51 int main()
    52 {
    53     //freopen("a.txt","r",stdin);
    54     //freopen("b.txt","w",stdout);
    55     int a,b,c;
    56     while(~scanf("%d%d%d",&N,&M,&X)) {
    57         for(int i=0;i<M;i++) {
    58             scanf("%d%d%d",&a,&b,&c);
    59             G[a].push_back(edge(b,c));
    60         }
    61         int sum=0;
    62         for(int i=1;i<=N;i++) {
    63             sum=max(sum,dijkstra(i,X)+dijkstra(X,i));
    64         }
    65         printf("%d
    ",sum);
    66     }
    67     return 0;
    68 }

     还有一种方法,首先求出点X到各个点i的最短路径,这就是奶牛返回的最短距离,然后把路径反向,在求点X到各个点i的最短距离,就是每个点到点X的最短距离。

     最后把两个距离相交即可。

     不过对于反向,不是很明白。

     时间直接从600多ms降到60多ms。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <set>
     8 #include <map>
     9 #include <string>
    10 #include <cmath>
    11 #include <cstdlib>
    12 #include <ctime>
    13 using namespace std;
    14 const int maxn= 1010;
    15 const int INF = 1<<29;
    16 struct edge{
    17     int to,cost;
    18     edge(){}
    19     edge(int x,int y) {
    20         to=x;
    21         cost=y;
    22     }
    23 };
    24 typedef pair<int,int>P;
    25 
    26 int N,M,X;
    27 vector<edge>G[maxn],RG[maxn];
    28 int d[maxn],rd[maxn];
    29 
    30 void dijkstra(int s) {
    31     priority_queue<P,vector<P>,greater<P> >que;
    32     for(int i=0;i<=N;i++) d[i]=INF;
    33     d[s]=0;
    34     que.push(P(0,s));
    35 
    36     while(!que.empty()) {
    37         P p=que.top(); que.pop();
    38         int v=p.second;
    39         if(d[v]<p.first) continue;
    40         for(int i=0;i<G[v].size();i++) {
    41             edge e=G[v][i];
    42             if(d[e.to]>d[v]+e.cost) {
    43                 d[e.to]=d[v]+e.cost;
    44                 que.push(P(d[e.to],e.to));
    45             }
    46         }
    47     }
    48 }
    49 
    50 int main()
    51 {
    52     //freopen("a.txt","r",stdin);
    53     //freopen("b.txt","w",stdout);
    54     int a,b,c;
    55     scanf("%d%d%d",&N,&M,&X);
    56         for(int i=0;i<M;i++) {
    57             scanf("%d%d%d",&a,&b,&c);
    58             G[a].push_back(edge(b,c));
    59             RG[b].push_back(edge(a,c)); //存储 反向边
    60         }
    61         dijkstra(X);   //第一次 dijkstra 是求X到各个点的距离
    62         //for(int i=1;i<=N;i++) printf("%d
    ",d[i]);
    63         for(int i=1;i<=N;i++) G[i]=RG[i];  //然后  把反向存储的边赋值给 G
    64       //  for(int i=1;i<=N;i++) {
    65           //  for(int j=0;j<G[i].size();j++)
    66               //  cout<<G[i][j].to<<" "<<G[i][j].cost<<endl;
    67        //}
    68         memcpy(rd,d,sizeof(d));  //把第一次的 最短距离  保存
    69 
    70         dijkstra(X);  //反向的 dijkstra 求出每个点到X的最短距离
    71         //for(int i=1;i<=N;i++) printf("%d
    ",d[i]);
    72         int sum=0;   //枚举最大和 
    73         for(int i=1;i<=N;i++) {
    74             sum=max(sum,d[i]+rd[i]);
    75         }
    76         printf("%d
    ",sum);
    77     return 0;
    78 }
  • 相关阅读:
    flash中网页跳转总结
    as3自定义事件
    mouseChildren启示
    flash拖动条移出flash无法拖动
    需要一个策略文件,但在加载此媒体时未设置checkPolicyFile标志
    Teach Yourself SQL in 10 Minutes
    电子书本地转换软件 Calibre
    Teach Yourself SQL in 10 Minutes
    Teach Yourself SQL in 10 Minutes
    Teach Yourself SQL in 10 Minutes – Page 31 练习
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4503364.html
Copyright © 2011-2022 走看看