zoukankan      html  css  js  c++  java
  • CF 1051F The Shortest Statement

    要求每两个点间的最短路,乍一看卧槽这怎么搞!

    乱搞。

    注意到m<=n+20,很显然要扯到生成树上。

    造一棵树,再将非树边加进来(这咋加啊)

    以每条非树边的端点为起点跑最短路,统计答案时取树上和非树上的最短距离就好

      1 #include<queue>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 int n,m,cnt,tot,q,id;
      7 int head[100005];
      8 int dep[100005];
      9 int fa[100005];
     10 int la[100005];
     11 long long dis[100005];
     12 int grand[100005];
     13 int son[100005];
     14 long long ans[100005];
     15 bool mrk[200005];
     16 int siz[100005];
     17 bool usd[100005];
     18 bool vis[100005];
     19 long long len[45][100005];
     20 int findfa(int x){
     21     if(fa[x]==x)return x;
     22     return fa[x]=findfa(fa[x]);
     23 }
     24 struct Query{
     25     int u;
     26     int v;
     27 }qry[100005];
     28 struct Edge{
     29     int fr;
     30     int to;
     31     int val;
     32     int nxt;
     33 }edge[210005];
     34 struct node{
     35     int u;
     36     long long w;
     37     node(int u,long long w):u(u),w(w){}
     38 };
     39 bool operator<(node a,node b){
     40     return a.w>b.w;
     41 }
     42 void init(){
     43     memset(head,-1,sizeof(head));
     44     memset(len,0x3f,sizeof(len));
     45 }
     46 void buildtree(){
     47     for(int i=1;i<=cnt;i+=2){
     48         int u=edge[i].fr;
     49         int v=edge[i].to;
     50         int fu=findfa(u);
     51         int fv=findfa(v);
     52         if(fu==fv)continue;
     53         fa[fv]=fu;
     54         tot++;mrk[i]=mrk[i+1]=true;
     55         if(tot==n-1)return;
     56     }
     57 }
     58 void addedge(int u,int v,int w){
     59     cnt++;
     60     edge[cnt].fr=u;
     61     edge[cnt].to=v;
     62     edge[cnt].val=w;
     63     edge[cnt].nxt=head[u];
     64     head[u]=cnt;
     65 }
     66 void dfs1(int u){
     67     siz[u]=1;son[u]=0;
     68     for(int i=head[u];i!=-1;i=edge[i].nxt){
     69         if(!mrk[i])continue;
     70         int v=edge[i].to;
     71         if(v==la[u])continue;
     72         la[v]=u;dep[v]=dep[u]+1;
     73         dis[v]=dis[u]+edge[i].val;
     74         dfs1(v);
     75         siz[u]+=siz[v];
     76         if(siz[v]>siz[son[u]])son[u]=v;
     77     }
     78 }
     79 void dfs2(int u){
     80     if(son[la[u]]!=u)grand[u]=u;
     81     else grand[u]=grand[la[u]];
     82     for(int i=head[u];i!=-1;i=edge[i].nxt){
     83         if(!mrk[i])continue;
     84         int v=edge[i].to;
     85         if(v==la[u])continue;
     86         dfs2(v);
     87     }
     88 }
     89 int lca(int u,int v){
     90     while(grand[u]!=grand[v]){
     91         if(dep[grand[u]]<dep[grand[v]]){
     92             swap(u,v);
     93         }
     94         u=la[grand[u]];
     95     }
     96     if(dep[u]>dep[v])swap(u,v);
     97     return u;
     98 }
     99 void dijk(int u){
    100     id++;len[id][u]=0;
    101     memset(vis,0,sizeof(vis));
    102     priority_queue<node>que;
    103     que.push(node(u,0));
    104     while(!que.empty()){
    105         node s=que.top();
    106         que.pop();
    107         if(vis[s.u])continue;
    108         vis[s.u]=true;
    109         for(int i=head[s.u];i!=-1;i=edge[i].nxt){
    110             int v=edge[i].to;
    111             if(len[id][v]>len[id][s.u]+edge[i].val){
    112                 len[id][v]=len[id][s.u]+edge[i].val;
    113                 que.push(node(v,len[id][v]));
    114             }
    115         }
    116     }
    117 }
    118 int main(){
    119     init();
    120     scanf("%d%d",&n,&m);
    121     for(int i=1;i<=n;i++){
    122         fa[i]=i;
    123     }
    124     for(int i=1;i<=m;i++){
    125         int u,v,w;
    126         scanf("%d%d%d",&u,&v,&w);
    127         addedge(u,v,w);
    128         addedge(v,u,w);
    129     }
    130     buildtree();
    131     for(int i=1;i<=cnt;i+=2){
    132         int u=edge[i].fr;
    133         int v=edge[i].to;
    134         if(!mrk[i]){
    135             if(!usd[u]){
    136                 dijk(u);
    137                 usd[u]=true;
    138             }
    139             if(!usd[v]){
    140                 dijk(v);
    141                 usd[v]=true;
    142             }
    143         }
    144     }
    145     dis[1]=0;dep[1]=1;
    146     dfs1(1);dfs2(1);
    147     scanf("%d",&q);
    148     for(int i=1;i<=q;i++){
    149         scanf("%d%d",&qry[i].u,&qry[i].v);
    150         int f=lca(qry[i].u,qry[i].v);
    151         ans[i]=dis[qry[i].u]+dis[qry[i].v]-dis[f]*2;
    152         for(int j=1;j<=id;j++){
    153             ans[i]=min(ans[i],len[j][qry[i].u]+len[j][qry[i].v]);
    154         }
    155     }
    156     for(int i=1;i<=q;i++){
    157         printf("%lld
    ",ans[i]);
    158     }
    159     return 0;
    160 }
  • 相关阅读:
    mybatis常用的配置解析
    shiro学习(一)
    三、maven学习-高级
    二、maven学习
    一、maven学习
    常用工具类
    三、redis学习(jedis连接池)
    一、redis学习(基础)
    校验用户名是否存在(ajax+jackson)
    Spring-简介-IOC理论推导
  • 原文地址:https://www.cnblogs.com/lnxcj/p/9873906.html
Copyright © 2011-2022 走看看