zoukankan      html  css  js  c++  java
  • 蓝书3.5 强连通分量

    T1 受欢迎的牛  bzoj 1051

    题解链接

    T2 最大半连通子图 bzoj 1093

    题目大意:

    一个半连通的图定义为对任意点对u v 存在路径u->v或v->u

    求给定图的最大半连通子图

    思路:

    可以知道 半连通子图一定为强连通分量缩点之后的链

    所以只需要求一个最长链然后记一下方案数 需要注意第二次建图之后会有很多重边

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 100100
    12 #define eps 1e-9
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int n,m,mod,to[MAXN*10],nxt[MAXN*10],fst[MAXN],cnt;
    22 int To[MAXN*10],Nxt[MAXN*10],Fst[MAXN],dp[MAXN],ans,res,num[MAXN];
    23 int st[MAXN],top,dfn[MAXN],low[MAXN],scc,stp,vis[MAXN],sz[MAXN],bl[MAXN];
    24 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    25 void Add(int u,int v) {Nxt[++cnt]=Fst[u],Fst[u]=cnt,To[cnt]=v;}
    26 void tarjan(int x)
    27 {
    28     dfn[x]=low[x]=++stp,st[++top]=x,vis[x]=1;
    29     for(int i=fst[x];i;i=nxt[i])
    30         if(!dfn[to[i]]) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}
    31         else if(!bl[to[i]]) low[x]=min(low[x],dfn[to[i]]);
    32     if(low[x]==dfn[x])
    33     {
    34         scc++;int now=0;
    35         while(now!=x)
    36             now=st[top--],vis[now]=0,bl[now]=scc,sz[scc]++;
    37     }
    38 }
    39 void build()
    40 {
    41     for(int x=1;x<=n;x++)
    42         for(int i=fst[x];i;i=nxt[i])
    43             if(bl[to[i]]!=bl[x]) Add(bl[x],bl[to[i]]);
    44 }
    45 void dfs(int x)
    46 {
    47     vis[x]=num[x]=1;
    48     bool v[MAXN]={0};
    49     for(int i=Fst[x];i;i=Nxt[i])
    50     {
    51         if(v[To[i]]) continue;
    52         v[To[i]]=1;
    53         if(!vis[To[i]]) dfs(To[i]);
    54         if(dp[x]==dp[To[i]]) (num[x]+=num[To[i]])%=mod;
    55         else if(dp[To[i]]>dp[x]) num[x]=num[To[i]],dp[x]=dp[To[i]];
    56     }
    57     dp[x]+=sz[x],res=max(res,dp[x]);
    58 }
    59 int main()
    60 {
    61     n=read(),m=read(),mod=read();int a,b;
    62     while(m--) {a=read(),b=read();add(a,b);}
    63     for(int i=1;i<=n;i++)
    64         if(!dfn[i]) tarjan(i);
    65     cnt=0;build();
    66     for(int i=1;i<=scc;i++)
    67         if(!vis[i]) dfs(i);
    68     for(int i=1;i<=scc;i++) if(dp[i]==res) (ans+=num[i])%=mod;
    69     printf("%d
    %d",res,ans);
    70 }
    View Code

    T3 Network of Schools poj 1236

    题目大意:

    有向图 在图上的点染色 颜色会沿边运动 

    求最少给多少个点染色会使整个图都被染色以及最少再加多少边使给任意一点染色都可以使整张图被染色

    思路:

    第一问很明显是缩点后入度为0的点个数

    第二问应该讲每条链的首尾相接 因此答案为缩点后max(入度为0,出度为0)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 10100
    12 #define eps 1e-9
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int n,m,mod,to[MAXN<<1],nxt[MAXN<<1],fst[MAXN],cnt;
    22 int To[MAXN<<1],Nxt[MAXN<<1],Fst[MAXN],ans,res,Ind[MAXN],Od[MAXN];
    23 int st[MAXN],top,dfn[MAXN],low[MAXN],scc,stp,vis[MAXN],sz[MAXN],bl[MAXN];
    24 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    25 void Add(int u,int v) {Nxt[++cnt]=Fst[u],Fst[u]=cnt,To[cnt]=v,Ind[v]++,Od[u]++;}
    26 void tarjan(int x)
    27 {
    28     dfn[x]=low[x]=++stp,st[++top]=x,vis[x]=1;
    29     for(int i=fst[x];i;i=nxt[i])
    30         if(!dfn[to[i]]) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}
    31         else if(!bl[to[i]]) low[x]=min(low[x],dfn[to[i]]);
    32     if(low[x]==dfn[x])
    33     {
    34         scc++;int now=0;
    35         while(now!=x)
    36             now=st[top--],vis[now]=0,bl[now]=scc,sz[scc]++;
    37     }
    38 }
    39 void build()
    40 {
    41     for(int x=1;x<=n;x++)
    42         for(int i=fst[x];i;i=nxt[i])
    43             if(bl[to[i]]!=bl[x]) Add(bl[x],bl[to[i]]);
    44 }
    45 int main()
    46 {
    47     n=read();int a;
    48     for(int i=1;i<=n;i++) while(1) {a=read();if(!a) break;add(i,a);}
    49     for(int i=1;i<=n;i++)
    50         if(!dfn[i]) tarjan(i);
    51     cnt=0;build();
    52     for(int i=1;i<=scc;i++) if(!Ind[i]) ans++;
    53     for(int i=1;i<=scc;i++) if(!Od[i]) res++;
    54     if(scc==1) printf("1
    0");
    55     else printf("%d
    %d",ans,max(res,ans));
    56 }
    View Code

    T4 间谍网络 luogu 1262

    题目大意:

    有向图 有些点可以染色 颜色会沿边运动 这些点染色花费不同 

    求是否能将整张图染色 以及最小费用

    思路:

    缩点之后求出每个点是否能被染色以及最小费用 

    判断所有入度为0的点是否能被染色 将他们的费用加起来

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 10100
    12 #define eps 1e-9
    13 using namespace std;
    14 inline int read()
    15 {
    16     int x=0,f=1;char ch=getchar();
    17     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    18     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    19     return x*f;
    20 }
    21 int n,m,to[MAXN],nxt[MAXN],fst[MAXN],cnt,val[MAXN],ok[MAXN];
    22 int To[MAXN],Nxt[MAXN],Fst[MAXN],ans,res,cst[MAXN],Ind[MAXN],rep[MAXN];
    23 int st[MAXN],top,dfn[MAXN],low[MAXN],scc,stp,vis[MAXN],Ok[MAXN],bl[MAXN];
    24 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    25 void Add(int u,int v) {Nxt[++cnt]=Fst[u],Fst[u]=cnt,To[cnt]=v,Ind[v]++;}
    26 void tarjan(int x)
    27 {
    28     dfn[x]=low[x]=++stp,st[++top]=x,vis[x]=1;
    29     for(int i=fst[x];i;i=nxt[i])
    30         if(!dfn[to[i]]) {tarjan(to[i]);low[x]=min(low[x],low[to[i]]);}
    31         else if(!bl[to[i]]) low[x]=min(low[x],dfn[to[i]]);
    32     if(low[x]==dfn[x])
    33     {
    34         scc++;int now=0;
    35         while(now!=x)
    36             now=st[top--],vis[now]=0,bl[now]=scc,Ok[scc]|=ok[now],cst[scc]=min(cst[scc],val[now]),rep[scc]=now;
    37     }
    38 }
    39 void build()
    40 {
    41     for(int x=1;x<=n;x++)
    42         for(int i=fst[x];i;i=nxt[i])
    43             if(bl[to[i]]!=bl[x]) Add(bl[x],bl[to[i]]);
    44 }
    45 int main()
    46 {
    47     memset(val,127,sizeof(val));memset(cst,127,sizeof(cst));
    48     n=read(),m=read();int a,b;
    49     while(m--) a=read(),ok[a]=1,val[a]=read();m=read();
    50     while(m--) {a=read(),b=read();add(a,b);}
    51     for(int i=1;i<=n;i++)
    52         if(!dfn[i]) tarjan(i);
    53     cnt=0;build();
    54     for(int i=1;i<=scc;i++) if(!Ind[i])
    55         if(!Ok[i]) {printf("NO
    %d",rep[i]);return 0;}
    56         else ans+=cst[i];
    57     printf("YES
    %d",ans);
    58 }
    View Code

    T5 Atm bzoj 1179

    题解链接

  • 相关阅读:
    (转) 一步一步学习ASP.NET 5 (五)- TypeScript
    #一周五# win10通用平台,无处不在的Xamarin,msbuild开源,MVP卢建晖的Asp.NET 5系列 (视频)
    (转) 一步一步学习ASP.NET 5 (四)- ASP.NET MVC 6四大特性
    (转) 一步一步学习ASP.NET 5 (三)- 认识新的Web结构
    #winhec# 开发人员刷屏看点 (视频)
    (翻译) TFS源代码控制的未来 (TFSVC vs. Git)
    (转) 一步一步学习ASP.NET 5 (二)- 通过命令行和sublime创建项目
    【JS教程03】函数
    【JS教程02】变量、数据类型及基本语法规范
    【JS教程01】JavaScript介绍与页面嵌入方式
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9372747.html
Copyright © 2011-2022 走看看