zoukankan      html  css  js  c++  java
  • BZOJ 1576[Usaco2009 Jan]安全路经Travel

    Solution:最短路树+并查集/树链剖分维护

      1 #include <cstdio>
      2 #include <queue>
      3 #include <algorithm>
      4 inline void swap(int &a,int &b)
      5 {
      6     register int tmp=b;
      7     b=a;a=tmp;
      8 }
      9 inline int read()
     10 {
     11     register int k=0,c=getchar(),f=1;
     12     while (c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
     13     while (c>='0'&&c<='9')k=k*10+c-'0',c=getchar();
     14     return k*f;
     15 }
     16 const int maxn=500000+100,inf=1<<30;
     17 struct edg{
     18     int x,too,del,nxt;
     19 }edge[maxn];
     20 struct qaq{
     21     int dis,pos;
     22 };
     23 struct mc{
     24     int a,b,len;
     25 }e[maxn];
     26 bool v[maxn],used[maxn];
     27 int vis[maxn];
     28 int n,m,tot,tot2,a,b,c,dist[maxn],last[maxn],h[maxn];
     29 int fq[maxn],eg[maxn],fa[maxn];
     30 std::priority_queue<qaq>q;
     31 bool operator<(qaq a,qaq b){return a.dis>b.dis;}
     32 inline void add(int a,int b,int c)
     33 {
     34     edge[++tot].nxt=last[a];
     35     last[a]=tot;
     36     edge[tot].too=b;
     37     edge[tot].x=a;
     38     edge[tot].del=c;
     39 }
     40 inline bool cmp(mc a,mc b)
     41 {
     42     return a.len<b.len;
     43 }
     44 int gf(int now)
     45 {
     46     return fa[now]==now?now:fa[now]=gf(fa[now]); 
     47 }
     48 inline void spfa()
     49 {
     50     for (register int i=1;i<=n;i++)dist[i]=inf;
     51     v[1]=1;dist[1]=0;q.push((qaq){0,1});
     52     while (!q.empty())
     53     {
     54         register int now=q.top().pos;q.pop();
     55         for (register int i=last[now];i;i=edge[i].nxt)
     56         {
     57             if (dist[edge[i].too]>edge[i].del+dist[now])
     58             {
     59                 dist[edge[i].too]=dist[now]+edge[i].del;
     60                 fq[edge[i].too]=now;
     61                 eg[edge[i].too]=i;
     62                 if (!v[edge[i].too])
     63                 {
     64                     v[edge[i].too]=1;
     65                     q.push((qaq){dist[edge[i].too],edge[i].too});
     66                 }
     67             }
     68         }
     69         v[now]=0;
     70     }
     71 }
     72 int main()
     73 {
     74     tot=1;
     75     n=read();m=read();
     76     for (register int i=1;i<=n;i++)fa[i]=i;
     77     for (register int i=1;i<=m;i++)a=read(),b=read(),c=read(),add(a,b,c),add(b,a,c);
     78     spfa();
     79     for (register int i=1;i<=n;i++)used[eg[i]]=used[eg[i]^1]=1;
     80     for (register int i=1;i<=tot;i++)
     81     if (!used[i])
     82     {
     83         e[++tot2].a=edge[i].x;e[tot2].b=edge[i].too;
     84         e[tot2].len=edge[i].del+dist[edge[i].x]+dist[edge[i].too];
     85     }
     86     std::sort(e+1,e+tot2+1,cmp);
     87     for(register int i=1;i<=tot2;i++)
     88     {
     89         register int a=e[i].a,b=e[i].b,f1=gf(a),f2=gf(b),lasta=0,lastb=0;
     90         while (f1!=f2)
     91         {
     92             if (dist[a]<dist[b])swap(a,b),swap(f1,f2),swap(lasta,lastb);
     93             if (!vis[a])
     94             {
     95                 vis[a]=i;
     96                 if (lasta)fa[lasta]=a;
     97             }else if (lasta)fa[lasta]=f1;
     98             lasta=f1;a=fq[lasta];f1=gf(a);
     99         }
    100     }
    101     for (register int i=2;i<=n;i++)
    102     if (!vis[i])printf("-1
    ");else printf("%d
    ",e[vis[i]].len-dist[i]);
    103 }
    View Code
  • 相关阅读:
    Python 类中方法的内部变量,命名加'self.'变成 self.xxx 和不加直接 xxx 的区别
    用foreach遍历 datagridView 指定列所有的内容
    treeView1.SelectedNode.Level
    YES NO 上一个 下一个
    正则 单词全字匹配查找 reg 边界查找 精确匹配 只匹配字符 不含连续的字符
    抓取2个字符串中间的字符串
    sqlite 60000行 插入到数据库只用不到2秒
    将多行文本以单行的格式保存起来 读和写 ini
    将秒转换成时间格式
    richtextbox Ctrl+V只粘贴纯文本格式
  • 原文地址:https://www.cnblogs.com/mczhuang/p/7688406.html
Copyright © 2011-2022 走看看