zoukankan      html  css  js  c++  java
  • BZOJ2200: [Usaco2011 Jan]道路和航线

    n<=25000个点m1<=50000条正权无向边m2<=50000条正负权有向边,保证有向边连接的无向边联通块形成一个拓扑图,求从s到每个点最短路。

    第一次发现不会最短路。没看题乱写迪杰无脑WA,很好。迪杰从来不能处理负权最短路,然后就开始啃题解。。http://www.cnblogs.com/staginner/archive/2012/10/01/2709487.html这篇代码不错,讲得也很好。

    在每个无向边联通块中找最短路可以直接迪杰。至于过度到不同的联通块,可以对无向图联通块形成的拓扑图按拓扑序来走。也就是说开一个队列记待搜集和每个集合在从前搜到的起点,在每次迪杰时利用并更新他们。

    过程有点长,需组织完整后一气呵成!

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<algorithm>
      4 #include<math.h>
      5 //#include<iostream>
      6 #include<queue>
      7 using namespace std;
      8 
      9 int n,m1,m2,s;
     10 #define maxn 25011
     11 #define maxm 100011
     12 const int inf=0x3f3f3f3f;
     13 struct Edge{int to,next,v;};
     14 struct qnode
     15 {
     16     int v,id;
     17     bool operator < (const qnode &b) const {return v<b.v;}
     18     bool operator > (const qnode &b) const {return v>b.v;}
     19 };
     20 int ufs[maxn];
     21 void ufsclear(int n)
     22 {
     23     for (int i=1;i<=n;i++) ufs[i]=i;
     24 }
     25 int find(int x) {return x==ufs[x]?x:(ufs[x]=find(ufs[x]));}
     26 void Union(int x,int y)
     27 {
     28     x=find(x),y=find(y);
     29     if (x==y) return;
     30     ufs[x]=y;
     31 }
     32 struct Graph
     33 {
     34     Edge road[maxm],fly[maxm];
     35     int froad[maxn],ffly[maxn],lr,lf;
     36     Graph()
     37     {
     38         memset(froad,0,sizeof(froad));
     39         memset(ffly,0,sizeof(ffly));
     40         lr=lf=2;
     41     }
     42     void in(Edge *edge,int *first,int &le,int x,int y,int v)
     43     {
     44         Edge &e=edge[le];
     45         e.to=y;e.v=v;
     46         e.next=first[x];
     47         first[x]=le++;
     48     }
     49     void insert(Edge *edge,int *first,int &le,int x,int y,int v)
     50     {
     51         in(edge,first,le,x,y,v);
     52         in(edge,first,le,y,x,v);
     53     }
     54     void in(int x,int y,int v) {in(fly,ffly,lf,x,y,v);}
     55     void insert(int x,int y,int v) {insert(road,froad,lr,x,y,v);}
     56     int deg[maxn];
     57     int que[maxn],head,tail;bool vis[maxn];
     58     void bfs()
     59     {
     60         que[head=(tail=1)-1]=s;
     61         vis[s]=1;
     62         memset(deg,0,sizeof(deg));
     63         while (head!=tail)
     64         {
     65             const int now=que[head++];
     66             for (int i=froad[now];i;i=road[i].next)
     67             {
     68                 Edge &e=road[i];
     69                 if (!vis[e.to]) vis[e.to]=1,que[tail++]=e.to;
     70             }
     71             for (int i=ffly[now];i;i=fly[i].next)
     72             {
     73                 Edge &e=fly[i];
     74                 deg[find(e.to)]++;
     75                 if (!vis[e.to]) vis[e.to]=1,que[tail++]=e.to;
     76             }
     77         }
     78     }
     79     Edge play[maxn];
     80     int fplay[maxn],lp;
     81     int dis[maxn];
     82     void inplay(int x,int y)
     83     {
     84         play[lp].to=y;
     85         play[lp].next=fplay[x];
     86         fplay[x]=lp++;
     87     }
     88     void dijkstra(int x)
     89     {
     90         priority_queue<qnode,vector<qnode>,greater<qnode> > q;
     91         for (int i=fplay[x];i;i=play[i].next)
     92         {
     93             Edge &e=play[i];
     94             q.push((qnode){dis[e.to],e.to});
     95             vis[e.to]=0;
     96         }
     97         while (!q.empty())
     98         {
     99             const int now=q.top().id,d=q.top().v;q.pop();
    100             if (vis[now]) continue;
    101             vis[now]=1;
    102             for (int i=froad[now];i;i=road[i].next)
    103             {
    104                 Edge &e=road[i];
    105                 if (dis[e.to]>d+e.v)
    106                 {
    107                     dis[e.to]=d+e.v;
    108                     q.push((qnode){dis[e.to],e.to});
    109                 }
    110             }
    111             for (int i=ffly[now];i;i=fly[i].next)
    112             {
    113                 Edge &e=fly[i];
    114                 if (dis[e.to]>d+e.v)
    115                 {
    116                     dis[e.to]=d+e.v;
    117                     if (!vis[e.to])
    118                     {
    119                         vis[e.to]=1;
    120                         inplay(find(e.to),e.to);
    121                     }
    122                 }
    123                 deg[find(e.to)]--;
    124                 if (!deg[ufs[e.to]]) que[tail++]=ufs[e.to];
    125             }
    126         }
    127     }
    128     void solve()
    129     {
    130         bfs();
    131         for (int i=1;i<=n;i++) dis[i]=inf;dis[s]=0;
    132         memset(fplay,0,sizeof(fplay));lp=2;
    133         que[head=(tail=1)-1]=find(s);
    134         inplay(ufs[s],s);
    135         memset(vis,0,sizeof(vis));
    136         while (head!=tail)
    137         {
    138             const int now=que[head++];
    139             dijkstra(now);
    140         }
    141         for (int i=1;i<=n;i++)
    142             printf(dis[i]==inf?"NO PATH
    ":"%d
    ",dis[i]);
    143     }
    144 }g;
    145 int x,y,v;
    146 int main()
    147 {
    148     scanf("%d%d%d%d",&n,&m1,&m2,&s);
    149     ufsclear(n);
    150     for (int i=1;i<=m1;i++)
    151     {
    152         scanf("%d%d%d",&x,&y,&v);
    153         g.insert(x,y,v);
    154         Union(x,y);
    155     }
    156     for (int i=1;i<=m2;i++)
    157     {
    158         scanf("%d%d%d",&x,&y,&v);
    159         g.in(x,y,v);
    160     }
    161     g.solve();
    162     return 0;
    163 }
    View Code
  • 相关阅读:
    PageAdmin Cms系统如何修改点击数(浏览数)
    最简js深浅拷贝说明
    实用的前端网址
    js的一些编码问题
    自己写一个文字过长显示省略号的函数
    垂直居中 和 水平居中
    js原码工具集
    url 、src 、href 的区别
    transform对定位元素的影响
    css实现一色多变化
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7450516.html
Copyright © 2011-2022 走看看