noip_最后一遍_2-图论部分

大体按照 数学 图论 dp 数据结构 这样的顺序

模板集 这个真的只有模板了………………

·spfa

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define maxn 100005
 5 ll n,m,k,l,a,b,c,d[maxn],s,visit[maxn];
 6 struct edge{int from,to,val;};
 7 vector<int>g[maxn];vector<edge>edges;
 8 void add_edge(int f,int t,int v){
 9     g[f].push_back(k);edges.push_back({f,t,v});k+=1;
10 }void spfa(int s){
11     for(int i=1;i<=n;i++)d[i]=2147483647;queue<int>q;q.push(s);
12     visit[s]=1,d[s]=0;
13     while(!q.empty()){int u=q.front();q.pop();visit[u]=0;
14         for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
15             if(d[e.to]>d[u]+e.val){d[e.to]=d[u]+e.val;
16                 if(!visit[e.to])q.push(e.to),visit[e.to]=1;
17             }
18         }
19     }
20 }
21 int main(){
22     cin>>n>>m>>s;for(int i=1;i<=m;i++)cin>>a>>b>>c,add_edge(a,b,c);spfa(s);
23     for(int i=1;i<=n;i++)cout<<d[i]<<" ";
24 }
View Code

 

判负圈和差分约束系统

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define maxn 100005
 5 ll n,m,k=0,l,a,b,c,d[maxn],s,visit[maxn],inv[maxn];
 6 struct edge{int from,to,val;};
 7 vector<int>g[maxn];vector<edge>edges;
 8 void add_edge(int f,int t,int v){
 9     g[f].push_back(k);edges.push_back({f,t,v});k+=1;
10 }bool spfa(int s){
11     for(int i=1;i<maxn;i++)d[i]=2147483647;queue<int>q;q.push(s);
12     visit[s]=1,d[s]=0;
13     while(!q.empty()){int u=q.front();q.pop();visit[u]=0;
14         for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
15             if(d[e.to]>d[u]+e.val){d[e.to]=d[u]+e.val;
16                 if(inv[e.to]>n)return 1;
17                 if(!visit[e.to])q.push(e.to),visit[e.to]=1,inv[e.to]++;
18             }
19         }
20     }return 0;
21 }
22 int main(){
23     cin>>l;while(l--){
24         cin>>n>>m;memset(visit,0,sizeof(visit));memset(inv,0,sizeof(inv));
25         for(int i=1;i<=m;i++){cin>>a>>b>>c;
26             add_edge(a,b,c);if(c>=0)add_edge(b,a,c);
27         }
28         if(spfa(1))cout<<"YE5"<<endl;else cout<<"N0"<<endl;
29         edges.clear();k=0;for(int i=1;i<maxn;i++)g[i].clear();
30     }
31 }
View Code

 

·dj

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define maxn 100005
 5 
 6 ll n,m,k,l,a,b,c,d[maxn],s,visit[maxn];
 7 struct edge{int from,to,val;};
 8 vector<int>g[maxn];vector<edge>edges;
 9 void add_edge(int f,int t,int v){
10     g[f].push_back(k);edges.push_back({f,t,v});k+=1;
11 }
12 
13 struct node{int u,d;
14     bool operator <(node b)const{
15         return d>b.d; 
16     }
17 };
18 void dj(int s){
19     for(int i=1;i<=n;i++)d[i]=2147483647;priority_queue<node>q;q.push({s,0});
20     visit[s]=1,d[s]=0;
21     while(!q.empty()){int u=q.top().u;q.pop();visit[u]=0;
22         for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
23             if(d[e.to]>d[u]+e.val){d[e.to]=d[u]+e.val;
24                 if(!visit[e.to])q.push({e.to,d[e.to]}),visit[e.to]=1;
25             }
26         }
27     }
28 }
29 
30 int main(){
31     cin>>n>>m>>s;
32     for(int i=1;i<=m;i++)scanf("%lld%lld%lld",&a,&b,&c),add_edge(a,b,c);
33     dj(s);for(int i=1;i<=n;i++)printf("%lld ",d[i]);
34     return 0;
35 }
View Code

 

·网络流

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define maxn 100005
 5 #define inf 2000000000
 6 ll n,m,k=0,l,a,b,c,d[maxn],s,t,visit[maxn],p[maxn],cur[maxn];
 7 struct edge{int from,to,cap,flow;};
 8 vector<int>g[maxn];vector<edge>edges;
 9 void add_edge(int f,int t,int v){g[f].push_back(k);edges.push_back({f,t,v,0});k+=1;g[t].push_back(k);edges.push_back({t,f,0,0});k+=1;}
10 bool bfs(){queue<int>q;q.push(s);visit[s]=1;
11     for(int i=1;i<=n;i++)d[i]=inf;d[s]=0;
12     while(!q.empty()){int u=q.front();q.pop();visit[u]=0;
13         for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
14             if(e.cap>e.flow&&d[e.to]>d[u]+1){d[e.to]=d[u]+1;
15                 if(!visit[e.to])q.push(e.to),visit[e.to]=1;
16             }
17         }
18     }return d[t]!=inf; 
19 }
20 ll dfs(int x,int a){if(a==0||x==t)return a;ll f=0,flow=0;
21     for(ll &i=cur[x];i<g[x].size();i++){edge &e=edges[g[x][i]];
22         if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))){
23             flow+=f,e.flow+=f,edges[g[x][i]^1].flow-=f;a-=f;
24         }
25     }return flow;
26 }
27 ll mf(ll s,ll t){ll flow=0;
28     while(bfs()){memset(cur,0,sizeof(cur));
29         flow+=dfs(s,inf);
30     }return flow;
31 }
32 int main(){cin>>n>>m>>s>>t;
33     for(int i=1;i<=m;i++)cin>>a>>b>>c,add_edge(a,b,c);
34     cout<<mf(s,t)<<endl;return 0;
35 }
View Code

 

 

·费用流

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define maxn 100005
 5 #define inf 2000000000
 6 ll n,m,k=0,l,aa,a[maxn],b,c,e,d[maxn],s,t,visit[maxn],p[maxn],cur[maxn],flow=0,cost=0;
 7 struct edge{ll from,to,cap,flow,cost;};
 8 vector<int>g[maxn];vector<edge>edges;
 9 void add_edge(int f,int t,int v,int c){g[f].push_back(k);edges.push_back({f,t,v,0,c});k+=1;
10 g[t].push_back(k);edges.push_back({t,f,0,0,-c});k+=1;}
11 ll bfs(){queue<int>q;q.push(s);visit[s]=1;a[s]=inf;
12     for(int i=1;i<=n;i++)d[i]=inf;d[s]=0;
13     while(!q.empty()){int u=q.front();q.pop();visit[u]=0;
14         for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
15             if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){d[e.to]=d[u]+e.cost;p[e.to]=g[u][i];
16                 a[e.to]=min(a[u],e.cap-e.flow);
17                 if(!visit[e.to])q.push(e.to),visit[e.to]=1;
18             }
19         }
20     }
21     if(d[t]==inf)return 0;
22     flow+=(long long)1*a[t];
23     cost+=(long long)1*d[t]*a[t];int u=t;
24     while(u!=s){
25         edges[p[u]].flow+=a[t];edges[p[u]^1].flow-=a[t];
26         u=edges[p[u]].from;
27     }
28     return true; 
29 }
30 int main(){cin>>n>>m>>s>>t;
31     for(int i=1;i<=m;i++)cin>>aa>>b>>c>>e,add_edge(aa,b,c,e);
32     while(bfs());
33     cout<<flow<<" "<<cost<<endl;
34     return 0;
35 }
View Code

 

·kruscall

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define maxn 2000005
 5 struct edge{int from,to,val;}e[maxn];
 6 bool cmp(edge a,edge b){return a.val<b.val;}
 7 ll n,m,k,l,a,b,c,fa[maxn],val=0;
 8 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
 9 void join(int x,int y){fa[find(x)]=find(y);}
10 int main(){cin>>n>>m;
11     for(int i=1;i<=n;i++)fa[i]=i;
12     for(int i=1;i<=m;i++)cin>>e[i].from>>e[i].to>>e[i].val;
13     sort(e+1,e+m+1,cmp);
14     for(int i=1;i<=m;i++){
15         if(find(e[i].from)==find(e[i].to))continue;
16         else join(e[i].from,e[i].to),val+=e[i].val; 
17     }cout<<val<<endl;
18     return 0;
19 }
View Code

 

·倍增lca

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 500005
 4 #define ll long long
 5 int n,m,k,l,a,b,s,c,fa[maxn][25],depth[maxn],visit[maxn];
 6 struct edge{int from,to;};vector<int>g[maxn];vector<edge>edges;
 7 void add_edge(int f,int t){g[f].push_back(k);g[t].push_back(k+1);
 8     edges.push_back({f,t});edges.push_back({t,f});k+=2;
 9 }void dfs(int u){visit[u]=1;fa[s][0]=s;
10     for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
11         if(visit[e.to])continue;depth[e.to]=depth[u]+1;fa[e.to][0]=u;dfs(e.to);
12     }
13 }int lca(int a,int b){if(depth[a]<depth[b])swap(a,b);
14     for(int i=21;i>=0;i--)if(depth[fa[a][i]]>=depth[b])a=fa[a][i];if(a==b)return a;
15     for(int i=21;i>=0;i--)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];return fa[a][0];
16 }
17 int main(){cin>>n>>m>>s;
18     for(int i=1;i<n;i++)scanf("%d%d",&a,&b),add_edge(a,b);
19     dfs(s);
20     for(int j=1;j<=21;j++)for(int i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1];
21     for(int i=1;i<=m;i++)scanf("%d%d",&a,&b),printf("%d\n",lca(a,b)); 
22 }
View Code

 

·树剖

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 100005
 4 #define lson (node<<1)
 5 #define rson (lson|1)
 6 int n,m,k=0,num=0,a,b,c,s[maxn],depth[maxn],top[maxn],val[maxn],fa[maxn],id[maxn],idx[maxn],sz[maxn],wson[maxn],visit[maxn];
 7 struct edge{int from,to;};vector<edge>edges;vector<int>g[maxn];
 8 void add_edge(int f,int t){g[f].push_back(k);g[t].push_back(k+1);k+=2;edges.push_back({f,t});edges.push_back({t,f});}
 9 int treesum[maxn*4],treemax[maxn*4];
10 inline int rd(){int res=0,f=1;char ch=getchar();
11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0'&&ch<='9'){res=res*10+(ch&15);ch=getchar();}return f*res;
13 }void pushdown(int node){treemax[node]=max(treemax[lson],treemax[rson]);treesum[node]=treesum[lson]+treesum[rson];}
14 void dfs1(int u){visit[u]=1;sz[u]=1;
15     for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];if(visit[e.to])continue;depth[e.to]=depth[u]+1,fa[e.to]=u;
16         dfs1(e.to);sz[u]+=sz[e.to];if(sz[e.to]>sz[wson[u]])wson[u]=e.to;}
17 }void dfs2(int u){visit[u]=1,id[u]=++num,idx[num]=u;
18     if(wson[u]!=0)top[wson[u]]=top[u],dfs2(wson[u]);
19     for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
20         if(visit[e.to]||wson[u]==e.to)continue;top[e.to]=e.to;dfs2(e.to);}
21 }void build(int node,int l,int r){if(l==r){treesum[node]=treemax[node]=val[idx[l]];return ;}int mid=(l+r)>>1;
22     build(lson,l,mid);build(rson,mid+1,r);pushdown(node);
23 }void add(int node,int l,int r,int x,int k){if(l==r){treemax[node]=treesum[node]=k;return ;}int mid=(l+r)>>1;
24     if(x<=mid)add(lson,l,mid,x,k);else if(x>=mid+1)add(rson,mid+1,r,x,k);pushdown(node);
25 }int querysum(int node,int l,int r,int x,int y){
26     if(l==x&&r==y){return treesum[node];}int mid=(l+r)>>1;
27     if(y<=mid)return querysum(lson,l,mid,x,y);else if(x>=mid+1)return querysum(rson,mid+1,r,x,y);
28     else return querysum(lson,l,mid,x,mid)+querysum(rson,mid+1,r,mid+1,y);
29 }int querymax(int node,int l,int r,int x,int y){
30     if(l==x&&r==y){return treemax[node];}int mid=(l+r)>>1;
31     if(y<=mid)return querymax(lson,l,mid,x,y);else if(x>=mid+1)return querymax(rson,mid+1,r,x,y);
32     else return max(querymax(lson,l,mid,x,mid),querymax(rson,mid+1,r,mid+1,y));
33 }
34 int findmax(int u,int v){int ans=-2000000000;
35     while(top[u]!=top[v]){if(depth[top[u]]<depth[top[v]])swap(u,v);
36         ans=max(ans,querymax(1,1,n,id[top[u]],id[u]));u=fa[top[u]];}
37     if(depth[u]<depth[v])swap(u,v);ans=max(ans,querymax(1,1,n,id[v],id[u]));return ans;
38 }int findsum(int u,int v){int ans=0;
39     while(top[u]!=top[v]){if(depth[top[u]]<depth[top[v]])swap(u,v);
40         ans+=querysum(1,1,n,id[top[u]],id[u]);u=fa[top[u]];
41     }if(depth[u]<depth[v])swap(u,v);ans+=querysum(1,1,n,id[v],id[u]);return ans;
42 }
43 int main(){n=rd();for(int i=1;i<n;i++)a=rd(),b=rd(),add_edge(a,b);
44     dfs1(1);memset(visit,0,sizeof(visit));dfs2(1);
45     for(register int i=1;i<=n;i++)val[i]=rd();
46     m=rd();build(1,1,n);
47     for(register int i=1;i<=m;i++){string hh;cin>>hh;
48         if(hh=="QMAX")a=rd(),b=rd(),printf("%d\n",findmax(a,b));
49         if(hh=="QSUM")a=rd(),b=rd(),printf("%d\n",findsum(a,b));
50         if(hh=="CHANGE")a=rd(),b=rd(),add(1,1,n,id[a],b);
51     }return 0;
52 }
View Code

 

·lct

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=10010;
 4 struct node{int fa,ch[2];bool reverse,is_root;}T[maxn];
 5 int n,m;
 6 void pushreverse(int x){if(!x)return;swap(T[x].ch[0],T[x].ch[1]);T[x].reverse^=1;}
 7 void pushdown(int x){
 8     if(T[x].reverse){
 9         pushreverse(T[x].ch[0]),pushreverse(T[x].ch[1]),T[x].reverse=false;
10     }
11 }int getson(int x){return x==T[T[x].fa].ch[1];}
12 void rotate(int x){if(T[x].is_root)return;
13     int k=getson(x),fa=T[x].fa;
14     int fafa=T[fa].fa;
15     T[fa].ch[k]=T[x].ch[k^1];
16     if(T[x].ch[k^1])T[T[x].ch[k^1]].fa=fa;
17     T[x].ch[k^1]=fa,T[fa].fa=x,T[x].fa=fafa;
18     if(!T[fa].is_root)T[fafa].ch[fa==T[fafa].ch[1]]=x;
19     else T[x].is_root=true,T[fa].is_root=false;
20 }void push(int x){if(!T[x].is_root)push(T[x].fa);pushdown(x);}
21 void splay(int x){push(x);
22     for(int fa;!T[x].is_root;rotate(x)){
23         if(!T[fa=T[x].fa].is_root){
24             rotate((getson(x)==getson(fa))?fa:x);
25         }
26     }
27 }void access(int x){
28     int y=0;do{
29         splay(x);T[T[x].ch[1]].is_root=true;
30         T[T[x].ch[1]=y].is_root=false;x=T[y=x].fa;
31     }while(x);
32 }bool judge(int u,int v){
33     while(T[u].fa)u=T[u].fa;while(T[v].fa)v=T[v].fa;
34     return u==v;
35 }void mroot(int x){access(x);splay(x);pushreverse(x);}
36 void link(int u,int v){mroot(u);T[u].fa=v;}
37 void cut(int u,int v){mroot(u);access(v);splay(v);
38     T[T[v].ch[0]].fa=T[v].fa;
39     T[T[v].ch[0]].is_root=true;
40     T[v].fa=0;T[v].ch[0]=0;
41 }void work(){
42     char opt[50];int u,v;
43     while(m--){cin>>opt>>u>>v;
44         if(opt[0]=='Q'){
45             if(judge(u,v))printf("Yes\n");
46             else printf("No\n");
47         }else if(opt[0]=='C')link(u,v);else if(opt[0]=='D')cut(u,v);
48     }
49 }int main(){cin>>n>>m;
50     for(int i=1;i<=n;i++){
51         T[i].reverse=T[i].fa=T[i].ch[0]=T[i].ch[1]=0;T[i].is_root=true;
52     }work();return 0;
53 }
View Code

 

·无向图tarjan只割顶 桥

 

·流图tarjan

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define maxn 10005
 5 int n,m,k,l,a,b,c,val[maxn],scc[maxn],cnt=0,num=0,dfn[maxn],low[maxn],ins[maxn],sz[maxn],in[maxn],out[maxn],d[maxn],mx=-1000000000;
 6 struct edge{int from,to;};vector<edge>edges;vector<int>g[maxn];vector<edge>edges2;vector<int>mp[maxn];
 7 void add_edge(int f,int t){g[f].push_back(k++),edges.push_back({f,t});} 
 8 stack<int>s;queue<int>q;
 9 void tarjan(int u){dfn[u]=low[u]=++num;s.push(u);ins[u]=1;
10     for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
11         if(!dfn[e.to]){tarjan(e.to);
12             low[u]=min(low[u],low[e.to]);
13         }else if(ins[e.to]){
14             low[u]=min(low[u],low[e.to]);
15         }
16     }if(dfn[u]==low[u]){cnt++;int now;
17         do{ now=s.top();s.pop();ins[now]=0;
18             scc[now]=cnt,sz[cnt]+=val[now];
19         }while(now!=u); 
20     }
21 }
22 int main(){
23     cin>>n>>m;for(int i=1;i<=n;i++)cin>>val[i];for(int i=1;i<=m;i++)cin>>a>>b,add_edge(a,b);
24     for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
25     for(int i=0;i<edges.size();i++){edge &e=edges[i];
26         if(scc[e.to]!=scc[e.from])
27         mp[scc[e.from]].push_back(l++),edges2.push_back({scc[e.from],scc[e.to]}),
28         in[scc[e.to]]++,out[scc[e.from]]++;
29     }
30     for(int i=1;i<=cnt;i++)if(!in[i])q.push(i),d[i]=sz[i];
31     while(!q.empty()){int u=q.front();q.pop();
32         for(int i=0;i<mp[u].size();i++){
33             edge &e=edges2[mp[u][i]];
34             in[e.to]--;d[e.to]=max(d[e.to],d[u]+sz[e.to]);
35             if(in[e.to]==0){
36                 q.push(e.to);
37             }
38         }
39     }for(int i=1;i<=cnt;i++)mx=max(d[i],mx);
40     cout<<mx<<endl;
41 }
View Code

 

·2-sat

 

 1 // luogu-judger-enable-o2
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 #define maxn 2000005
 5 int n,m,k=0,l,a,b,c,d,num=0,root,cnt=0,ins[maxn],val[maxn],dfn[maxn],low[maxn],scc[maxn];
 6 struct edge{int from,to;};
 7 vector<edge>edges;vector<int>g[maxn];stack<int>s; 
 8 void tarjan(int u){
 9     s.push(u);ins[u]=1;dfn[u]=low[u]=++num;
10     for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
11         if(!dfn[e.to]){tarjan(e.to);
12             low[u]=min(low[u],low[e.to]);
13         }else if(ins[e.to])low[u]=min(low[u],low[e.to]);
14     }if(dfn[u]==low[u]){int y;cnt++;
15         do{y=s.top();s.pop();
16             scc[y]=cnt,ins[y]=0;
17         }while(u!=y);
18     }
19 }
20 int main(){scanf("%d%d",&n,&m);
21     for(register int i=1;i<=m;i++){
22         scanf("%d%d%d%d",&a,&b,&c,&d);
23         edges.push_back({c+((1-d)*n),a+(b*n)});
24         edges.push_back({a+((1-b)*n),c+(d*n)});
25         g[c+((1-d)*n)].push_back(k);
26         g[a+((1-b)*n)].push_back(k+1);k+=2;
27     }
28     for(register int i=1;i<=2*n;i++)if(!dfn[i])tarjan(i);
29     for(register int i=1;i<=n;i++){
30         if(scc[i]==scc[i+n]){printf("IMPOSSIBLE\n");return 0;}
31         else val[i]=scc[i]>scc[i+n];
32     }
33     printf("POSSIBLE\n");
34     for(register int i=1;i<=n;i++)printf("%d ",val[i]);
35     return 0;
36 }
View Code

 

·点分(这个考就没意思了………………)打的聪聪可可那个

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 20005
 4 struct edge{int from,to,val;};
 5 vector<int>g[maxn];vector<edge>edges;
 6 int n,m,k=0,a,b,c,d[maxn],root,done[maxn],sz[maxn],msz[maxn],tag[maxn],sum,visit[maxn],ans=0;
 7 void add_edge(int f,int t,int v){g[f].push_back(k);edges.push_back({f,t,v%3});g[t].push_back(k+1);edges.push_back({t,f,v%3});k+=2;}
 8 int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
 9 void dfs(int u){visit[u]=1;msz[u]=0;
10     for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
11         if(visit[e.to]||done[e.to])continue;
12         dfs(e.to);sz[u]+=sz[e.to];msz[u]=max(sz[e.to],msz[u]);
13     }msz[u]=max(sum-sz[u],msz[u]);
14     if(msz[root]>msz[u]||root==0)root=u;
15 }void dfs2(int u){visit[u]=1;tag[d[u]]++;
16     for(int i=0;i<g[u].size();i++){
17         edge &e=edges[g[u][i]];if(visit[e.to]||done[e.to])continue;
18         d[e.to]=d[u]+e.val;d[e.to]%=3;dfs2(e.to);
19     }
20 }int cal(int u,int v){tag[0]=tag[1]=tag[2]=0,d[u]=v,dfs2(u);
21     memset(visit,0,sizeof(visit));memset(d,0,sizeof(d));
22     return tag[1]*tag[2]*2+tag[0]*tag[0];
23 }void solve(int s){ans+=cal(s,0);done[s]=1;
24     for(int i=0;i<g[s].size();i++){edge &e=edges[g[s][i]];
25         if(done[e.to])continue;
26         ans-=cal(e.to,e.val),root=0,sum=sz[e.to];
27         for(int i=1;i<=n;i++)sz[i]=1;
28         memset(msz,0,sizeof(msz));dfs(e.to);
29         memset(visit,0,sizeof(visit));solve(root);
30     }
31 }int main(){cin>>n;sum=n;for(int i=1;i<=n;i++)sz[i]=1;
32     for(int i=1;i<n;i++)scanf("%d%d%d",&a,&b,&c),add_edge(a,b,c);
33     dfs(1),memset(visit,0,sizeof(visit)),solve(root);
34     int dd=gcd(ans,n*n);cout<<ans/dd<<"/"<<n*n/dd<<endl;
35 }
View Code

 

·拓扑排序和基环树

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define mod 80112002
 4 #define ll long long
 5 #define maxn 100005
 6 ll n,m,k,l,in[maxn],out[maxn],visit[maxn],a,b,f[maxn];
 7 struct edge{int from,to,val;};
 8 vector<int>g[maxn];vector<edge>edges;
 9 void add_edge(int f,int t){g[f].push_back(k++);edges.push_back({f,t});in[b]++,out[a]++;}
10 void dfs(int u){visit[u]=1;
11     for(int i=0;i<g[u].size();i++){
12         edge &e=edges[g[u][i]];f[e.to]+=f[u],f[e.to]%=mod;if(--in[e.to]==0)dfs(e.to);
13     }
14 }
15 int main(){cin>>n>>m;for(int i=1;i<=m;i++)cin>>a>>b,add_edge(a,b);
16     for(int i=1;i<=n;i++){
17         if(!in[i]&&out[i]&&!visit[i])f[i]=1,dfs(i);
18     }for(int i=1;i<=n;i++){if(!out[i])l+=f[i],l%=mod;}cout<<l%mod<<endl;
19     return 0;
20 }
View Code

 

·缩点

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 #define maxn 10005
 5 int n,m,k,l,a,b,c,val[maxn],scc[maxn],cnt=0,num=0,dfn[maxn],low[maxn],ins[maxn],sz[maxn],in[maxn],out[maxn],d[maxn],mx=-1000000000;
 6 struct edge{int from,to;};vector<edge>edges;vector<int>g[maxn];vector<edge>edges2;vector<int>mp[maxn];
 7 void add_edge(int f,int t){g[f].push_back(k++),edges.push_back({f,t});} 
 8 stack<int>s;queue<int>q;
 9 void tarjan(int u){dfn[u]=low[u]=++num;s.push(u);ins[u]=1;
10     for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];
11         if(!dfn[e.to]){tarjan(e.to);
12             low[u]=min(low[u],low[e.to]);
13         }else if(ins[e.to]){
14             low[u]=min(low[u],low[e.to]);
15         }
16     }if(dfn[u]==low[u]){cnt++;int now;
17         do{ now=s.top();s.pop();ins[now]=0;
18             scc[now]=cnt,sz[cnt]+=val[now];
19         }while(now!=u); 
20     }
21 }
22 int main(){
23     cin>>n>>m;for(int i=1;i<=n;i++)cin>>val[i];for(int i=1;i<=m;i++)cin>>a>>b,add_edge(a,b);
24     for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
25     for(int i=0;i<edges.size();i++){edge &e=edges[i];
26         if(scc[e.to]!=scc[e.from])
27         mp[scc[e.from]].push_back(l++),edges2.push_back({scc[e.from],scc[e.to]}),
28         in[scc[e.to]]++,out[scc[e.from]]++;
29     }
30     for(int i=1;i<=cnt;i++)if(!in[i])q.push(i),d[i]=sz[i];
31     while(!q.empty()){int u=q.front();q.pop();
32         for(int i=0;i<mp[u].size();i++){
33             edge &e=edges2[mp[u][i]];
34             in[e.to]--;d[e.to]=max(d[e.to],d[u]+sz[e.to]);
35             if(in[e.to]==0){
36                 q.push(e.to);
37             }
38         }
39     }for(int i=1;i<=cnt;i++)mx=max(d[i],mx);
40     cout<<mx<<endl;
41 }
View Code

 

转载于:https://www.cnblogs.com/iboom/p/9912389.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值