zoukankan      html  css  js  c++  java
  • 牛客网NOIP赛前集训营 第6场 T1 最长路

    【题解】

      先建反向图,然后跑拓扑排序求出最长路。

      将所有的点按照最长路从小到大分层,把上一层连向这一层的边按照边权为第一关键字、起点的排名为第二关键字排序。

      按照这个顺序更新这一层的答案,按照这一层每个点被更新的顺序得到这一层的点的排名。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define LL long long
     5 #define rg register
     6 #define N 1000010
     7 #define Mod (998244353)
     8 using namespace std;
     9 int n,m,tot,cnt,last[N],in[N],dis[N],q[N],rk[N],ans[N];
    10 struct edge{int to,pre,dis;}e[N];
    11 struct poi{int dis,num;}p[N];
    12 struct rec{int w,rk,from,to;}r[N];
    13 inline int read(){
    14     int k=0,f=1; char c=getchar();
    15     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    16     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    17     return k*f;
    18 }
    19 inline bool cmp(rec a,rec b){
    20     if(a.w==b.w) return a.rk<b.rk;
    21     return a.w<b.w;
    22 }
    23 inline bool cmp2(poi a,poi b){return a.dis<b.dis;}
    24 inline void topu(int x){
    25     int front=0,rear=1; q[1]=x;
    26     while(front<rear){
    27         int now=q[++front];
    28         for(rg int i=last[now],to;i;i=e[i].pre){
    29             to=e[i].to;
    30             dis[to]=max(dis[to],dis[now]+1);
    31             if(!(--in[to])) q[++rear]=to; 
    32         }
    33     }
    34 }
    35 int main(){
    36     n=read(); m=read();
    37     for(rg int i=1;i<=m;i++){
    38         int u=read(),v=read(),d=read(); in[u]++;
    39         e[++tot]=(edge){u,last[v],d}; last[v]=tot;
    40     }
    41     for(rg int i=1;i<=n;i++)if(!in[i]&&!dis[i]) topu(i);
    42     for(rg int i=1;i<=n;i++){
    43         p[i].num=i;
    44         if(in[i]) p[i].dis=2e9; else p[i].dis=dis[i];
    45     }
    46     sort(p+1,p+1+n,cmp2);
    47     int st=1,ed=1;
    48     while(st<=n){
    49         tot=0;
    50         while(p[ed].dis==p[st].dis&&ed<=n){
    51             int now=p[ed].num;
    52 //            printf("now=%d ed=%d
    ",now,ed);
    53             for(rg int i=last[now],to;i;i=e[i].pre){
    54                 if(dis[to=e[i].to]==dis[now]+1) r[++tot]=(rec){e[i].dis,rk[now],now,to};
    55             }
    56             ed++;
    57         }  
    58         sort(r+1,r+1+tot,cmp);
    59         for(rg int i=1;i<=tot;i++)if(!ans[r[i].to]){
    60 //            printf("%d %d %d %d %d
    ",r[i].to,r[i].from,r[i].w,ans[r[i].from],ans[r[i].to]);
    61             ans[r[i].to]=(1ll*ans[r[i].from]*29+r[i].w*29)%Mod;
    62             rk[r[i].to]=++cnt;
    63         }
    64         st=ed;
    65     }
    66     for(rg int i=1;i<=n;i++) if(in[i]>0) puts("Infinity"); else printf("%d
    ",ans[i]%Mod);
    67     return 0;
    68 }
  • 相关阅读:
    [leetcode]Search for a Range
    Codeforces 432 D. Prefixes and Suffixes
    FZU2127:养鸡场
    安德鲁斯----多媒体编程
    hive RegexSerDe View
    Android 随着输入框控件的清除功能ClearEditText,抄IOS输入框
    Eclipse——热键&amp;Help
    图像形态学操作—腐蚀扩展深度
    基于速度学习机的局部感受野
    Qt:使用Model-View,动态的加载显示数据
  • 原文地址:https://www.cnblogs.com/DriverLao/p/9835289.html
Copyright © 2011-2022 走看看