• 【BZOJ】【2208】【JSOI2010】连通数


    题解:

      1.Tarjan缩点以后对每个连通分量进行深搜,看能到哪些连通分量,能到达的所有连通分量的size之和记为sum。则第i个连通分量对答案的贡献为size[i]*sum(到其他连通分量)+size[i]*size[i](本身互相可达)

      2.在网上搜了一下……这题可以直接dfs过……汗。“正解”是Tarjan缩点+拓扑排序+状态压缩

      1 /**************************************************************
      2     Problem: 2208
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:9476 ms
      7     Memory:64772 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 2208
     11 #include<vector>
     12 #include<cstdio>
     13 #include<cstdlib>
     14 #include<cstring>
     15 #include<iostream>
     16 #include<algorithm>
     17 #define rep(i,n) for(int i=0;i<n;++i)
     18 #define F(i,j,n) for(int i=j;i<=n;++i)
     19 #define D(i,j,n) for(int i=j;i>=n;--i)
     20 using namespace std;
     21 const int N=2015;
     22 typedef long long LL;
     23 void read(int &v){
     24     v=0; int sign=1; char ch=getchar();
     25     while(ch<'0'||ch>'9') {if (ch=='-') sign=-1; ch=getchar();}
     26     while(ch>='0'&&ch<='9') {v=v*10+ch-'0'; ch=getchar();}
     27     v*=sign;
     28 }
     29 /*******************tamplate********************/
     30 int to1[N*N],head1[N],next1[N*N],cnt=0;
     31 int to2[N*N],head2[N],next2[N*N];
     32 void ins1(int x,int y){
     33     to1[++cnt]=y; next1[cnt]=head1[x]; head1[x]=cnt;
     34 }
     35 void ins2(int x,int y){
     36     to2[++cnt]=y; next2[cnt]=head2[x]; head2[x]=cnt;
     37 }
     38 /***********************************************/
     39 int n,m;
     40 int dfn[N],low[N],dfs_clock=0,belong[N],num,size[N];
     41 int st[N],top=0;
     42 bool in[N];
     43 void tarjan(int x){
     44     int y;
     45     dfn[x]=low[x]=++dfs_clock;
     46     st[top++]=x;
     47     in[x]=1;
     48     for(int i=head1[x];i;i=next1[i]){
     49         y=to1[i];
     50         if (!dfn[y]){
     51             tarjan(y);
     52             low[x]=min(low[x],low[y]);
     53         }
     54         else if (in[y]) low[x]=min(low[x],dfn[y]);
     55     }
     56     if (low[x]==dfn[x]){
     57         num++; size[num]=0;
     58         for(y=0;y!=x;){
     59             y=st[--top];
     60             in[y]=0;
     61             belong[y]=num;
     62             size[num]++;
     63         }
     64     }
     65 }
     66 void rebuild(){
     67     cnt=0;
     68     F(x,1,n)
     69         for(int i=head1[x];i;i=next1[i])
     70             if (belong[x]!=belong[to1[i]])
     71                 ins2(belong[x],belong[to1[i]]);
     72 }
     73 /***********************************************/
     74 bool vis[N];
     75 int sum=0;
     76 void dfs(int x){
     77     int y;
     78     for(int i=head2[x];i;i=next2[i]){
     79         y=to2[i];
     80         if (!vis[y]){
     81             vis[y]=1;
     82             sum+=size[y];
     83             dfs(y);
     84         }
     85     }
     86 }      
     87 void solve(){
     88     LL ans=0;
     89     F(i,1,num){
     90         memset(vis,0,sizeof vis);
     91         sum=0;
     92         dfs(i);
     93         ans+=size[i]*sum+size[i]*size[i];
     94     }
     95     printf("%lld
    ",ans);
     96 }
     97 int main(){
     98     #ifndef ONLINE_JUDGE
     99     freopen("input.txt","r",stdin);
    100     #endif
    101     read(n);
    102     char s[N];
    103     F(i,1,n){
    104         scanf("%s",s);
    105         rep(j,strlen(s))
    106             if (s[j]=='1') ins1(i,j+1);
    107     }
    108     F(i,1,n) if (!dfn[i]) tarjan(i);
    109     rebuild();
    110     solve();
    111     return 0;
    112 }
    View Code
  • 相关阅读:
    Objective-C method及相关方法分析
    java对象和json数据转换实现方式1-使用json-lib实现
    java中TCP传输协议
    【剑指Offer学习】【面试题27:二叉搜索树与双向链表】
    4.2.2 MINUS
    Hadoop for .NET Developers
    在命名空间下定义类型
    Android NDK课程录制完毕上线
    全然同态加密
    从golang的垃圾回收说起(下篇)
  • 原文地址:https://www.cnblogs.com/Tunix/p/4231368.html
Copyright © 2020-2023  润新知