codeforces 757F Team Rocket Rises Again

链接:http://codeforces.com/problemset/problem/757/F

正解:灭绝树。

mdzz倍增lca的根节点深度必须是1。。我因为这个错误调了好久。

我们考虑先求最短路,求完最短路以后,我们就能对原来的无向图构造一个DAG。当我们构造完DAG以后,我们要求的东西已经很明显。那就是删掉一个点以后,最多有多少个点与S不连通。那么,我们按照套路,将DAG跑一遍拓扑排序,建出灭绝树。然后求出除了S点以外的最大size就行了。

  1 //It is made by wfj_2048~
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <complex>
  5 #include <cstring>
  6 #include <cstdlib>
  7 #include <cstdio>
  8 #include <vector>
  9 #include <cmath>
 10 #include <queue>
 11 #include <stack>
 12 #include <map>
 13 #include <set>
 14 #define inf (1LL<<60)
 15 #define M (300010)
 16 #define N (200010)
 17 #define il inline
 18 #define RG register
 19 #define ll long long
 20 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
 21
 22 using namespace std;
 23
 24 struct edge{ int nt,to; ll dis; }g[2*M],g1[2*M],g2[2*M];
 25
 26 int head[N],head1[N],head2[N],q[20*N],d[N],vis[N],dep[N],sz[N],f[22][N],S,n,m,num,num1,num2,ans;
 27 ll dis[N];
 28
 29 il int gi(){
 30     RG int x=0,q=1; RG char ch=getchar(); while ((ch<‘0‘ || ch>‘9‘) && ch!=‘-‘) ch=getchar();
 31     if (ch==‘-‘) q=-1,ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘) x=x*10+ch-48,ch=getchar(); return q*x;
 32 }
 33
 34 il void insert(RG int from,RG int to,RG ll dis){ g[++num]=(edge){head[from],to,dis},head[from]=num; return; }
 35
 36 il void insert1(RG int from,RG int to){ g1[++num1]=(edge){head1[from],to},head1[from]=num1; return; }
 37
 38 il void insert2(RG int from,RG int to){ g2[++num2]=(edge){head2[from],to},head2[from]=num2; return; }
 39
 40 il void spfa(RG int S){
 41     for (RG int i=1;i<=n;++i) dis[i]=inf;
 42     RG int h=0,t=1; dis[S]=0,vis[S]=1,q[t]=S;
 43     while (h<t){
 44     RG int x=q[++h];
 45     for (RG int i=head[x],v=g[i].to;i;i=g[i].nt,v=g[i].to)
 46         if (dis[v]>dis[x]+g[i].dis){
 47         dis[v]=dis[x]+g[i].dis;
 48         if (!vis[v]) vis[v]=1,q[++t]=v;
 49         }
 50     vis[x]=0;
 51     }
 52     return;
 53 }
 54
 55 il void dfs1(RG int x){
 56     vis[x]=1;
 57     for (RG int i=head[x],v=g[i].to;i;i=g[i].nt,v=g[i].to)
 58     if (dis[v]==dis[x]+g[i].dis){
 59         insert1(x,v),insert2(v,x),d[v]++;
 60         if (!vis[v]) dfs1(v);
 61     }
 62     return;
 63 }
 64
 65 il void dfs2(RG int x){
 66     sz[x]=1; RG int v;
 67     for (RG int i=head[x];i;i=g[i].nt)
 68     v=g[i].to,dfs2(v),sz[x]+=sz[v];
 69     if (x!=S) ans=max(ans,sz[x]); return;
 70 }
 71
 72 il int lca(RG int u,RG int v){
 73     if (u==v) return u; if (dep[u]<dep[v]) swap(u,v);
 74     for (RG int i=20;i>=0;--i)
 75     if (dep[f[i][u]]>=dep[v]) u=f[i][u];
 76     if (u==v) return u;
 77     for (RG int i=20;i>=0;--i)
 78     if (f[i][u]!=f[i][v]) u=f[i][u],v=f[i][v];
 79     return f[0][u];
 80 }
 81
 82 il void topsort(){
 83     RG int h=0,t=1; q[t]=S,dep[S]=1; //不赋初值会跪烂!!!
 84     while (h<t){
 85     RG int x=q[++h],v;
 86     for (RG int i=head1[x];i;i=g1[i].nt){
 87         v=g1[i].to,d[v]--;
 88         if (!d[v]){
 89         q[++t]=v; RG int Lca=0;
 90         for (RG int j=head2[v];j;j=g2[j].nt)
 91             if (!Lca) Lca=g2[j].to; else Lca=lca(Lca,g2[j].to);
 92         insert(Lca,v,0),f[0][v]=Lca,dep[v]=dep[Lca]+1;
 93         for (RG int j=1;j<=20;++j) f[j][v]=f[j-1][f[j-1][v]];
 94         }
 95     }
 96     }
 97     return;
 98 }
 99
100 il void work(){
101     n=gi(),m=gi(),S=gi();
102     for (RG int i=1,u,v,w;i<=m;++i){
103     u=gi(),v=gi(),w=gi();
104     insert(u,v,(ll)w),insert(v,u,(ll)w);
105     }
106     spfa(S); dfs1(S); memset(head,0,sizeof(head)),num=0;
107     topsort(); dfs2(S); printf("%d\n",ans); return;
108 }
109
110 int main(){
111     File("757F");
112     work();
113     return 0;
114 }
时间: 2024-12-25 11:29:14

codeforces 757F Team Rocket Rises Again的相关文章

codeforces 932E Team Work

codeforces 932E 题目描述 求\(\sum_{i=1}^{n}{(^n_i)i^k}\space mod\space10^9+7\) 思路 本题\(n\)的范围很大\((n\le10^9)\),但\(k\)在可接受的范围内\((k\le5000)\),我们可以尝试从\(k\)入手. 构造\((1+x)^n=\sum_{i=0}^n{(^n_i)x^i}\) 对等式两边求导并同乘\(x\),得 \[ nx(1+x)^{n-1}=\sum_{i=1}^n\big(^n_i\big)ix

Codeforces 932E Team Work 数学

Team Work 发现网上没有我这种写法.. i ^ k我们可以理解为对于每个子集我们k个for套在一起数有多少个. 那么我们问题就变成了 任意可重复位置的k个物品属于多少个子集. 然后我们枚举k个物品所占位置的个数 i , 然后需要计算有多少种方案能把k个不同物品放入i个桶中. 这个东西可以用dp[ i ][ j ] 表示 i 个物品放入 j 个桶中的方案数. dp[ i ][ j ] = dp[ i - 1 ][ j ] * j + dp[ i - 1 ][ j - 1 ] * j 然后就

CodeForces - 401C Team(简单构造)

题意:要求构造一个字符串,要求不能有连续的两个0在一起,也不能有连续的三个1在一起. 分析: 1.假设有4个0,最多能构造的长度为11011011011011,即10个1,因此若m > (n + 1) * 2则肯定不能构造成功. 2.假设有4个0,则至少有3个1,若小于3个,则会有两个连续的0在一起,所以n > m + 1则肯定不能构造成功. 3.当n==m+1时,一定是01串. 4.当m>=n时,应以1为开头构造,根据m和n的个数决定放1个1还是2个连续的1. #include<

CodeForces 490A Team Olympiad

题意: 编号为1.2.3的同学分成一组  问  最多形成多少组  并输出方案 思路: 模拟3个栈暴力 代码: #include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<map> #include<set> #include<vector> #include<queu

codeforces 757F

最短路DAG + 支配树 支配树是一种解决必经点问题的数据结构. 在dijkstra中可以处理处拓扑序,进而建立最短路DAG 但由于求最短路时,可能会有未联通的点,所以在用最短路求拓扑序的时候,要把被更新的点pop掉. 附代码 #include "bits/stdc++.h" using namespace std; #define maxn 2222222 #define For(i ,j ,n) for(int i = j; i<=n; i++) #define pa pai

CodeForces 1316E Team Building

Description 你需要组建一支排球队.为了组织一支排球队,你需要为队伍里的 $p$ 个不同的位置,从 $n$ 个人中选出 $p$ 个人,且每个位置上都恰好有一个人.另外还需要从剩下的人中选出恰好 $k$ 个人作为观众. 对于第 $i$ 个人,已知他作为观众时能为队伍增加 $a_i$ 点力量,还有他在队伍的第 $j$ 个位置上时能为队伍增加 $s_{i,j}$ 点力量. 请问这只排球队力量的最大值是多少? Solution 看到 $p$ 很小,考虑状态压缩 DP. 这里先把每个人按照 $a

学习总结:斯特林数( Stirling number )

基本定义 第一类斯特林数:$1 \dots n$的排列中恰好有$k$个环的个数:或是,$n$元置换可分解为$k$个独立的轮换的个数.记作 $$ \begin{bmatrix} n \\ k \end{bmatrix}. $$ 第二类斯特林数:将$n$个元素分成$k$个非空集合的方案数.记作 $$ \begin{Bmatrix} n \\ k \end{Bmatrix}. $$ 根据定义,我们有 $$ \sum_{k=0}^n \begin{bmatrix} n \\ k \end{bmatrix

Codeforces Round #486 (Div. 3) A. Diverse Team

Codeforces Round #486 (Div. 3) A. Diverse Team 题目连接: http://codeforces.com/contest/988/problem/A Description There are n students in a school class, the rating of the i-th student on Codehorses is ai. You have to form a team consisting of k students

Codeforces Round #516 (Div. 2, by Moscow Team Olympiad)

Codeforces Round #516 (Div. 2, by Moscow Team Olympiad) https://codeforces.com/contest/1064 A 1 #include<bits/stdc++.h> 2 #define pb push_back 3 using namespace std; 4 5 bool Check(int a,int b,int c){ 6 if(a+b>c&&b+c>a&&a+c>