设为首页 加入收藏

TOP

ZOJ 3795 Grouping 缩点拓扑序下求最长链
2015-07-24 06:51:29 来源: 作者: 【 】 浏览:80
Tags:ZOJ 3795 Grouping 拓扑 最长

题意:给定n个点,m条有向边。

把点分成几个集合使得每个集合中的任意2点都不可达(一个集合只存放一个点也可以)

问最少需要分成几个集合。

如果没有环,则这个题目就是求有向图的最长链,拓扑序下跑bfs即可。

但是有环,所以把环缩点成新点x,而点x的点权就是x点在原图中对应的顶点个数。

缩点后就是有向无环图,继续跑一个拓扑序。


#include 
  
   
#include 
   
     #include 
    
      #include 
     
       #include 
      
        #include 
       
         #include 
        
          #include 
          #include 
          
            #include 
           
             #include 
            
              #include 
             
               using namespace std; #define N 100010 //N为最大点数 #define M 301000 //M为最大边数 int n, m;//n m 为点数和边数 struct Edge{ int from, to, nex; bool sign;//是否为桥 }edge[M<<1]; int head[N], edgenum; void add(int u, int v){//边的起点和终点 Edge E={u, v, head[u], false}; edge[edgenum] = E; head[u] = edgenum++; } int DFN[N], Low[N], Stack[N], top, Time; //Low[u]是点集{u点及以u点为根的子树} 中(所有反向弧)能指向的(离根最近的祖先v) 的DFN[v]值(即v点时间戳) int taj;//连通分支标号,从1开始 int Belong[N];//Belong[i] 表示i点属于的连通分支 bool Instack[N]; vector
              
                bcc[N]; //标号从1开始 void tarjan(int u ,int fa){ DFN[u] = Low[u] = ++ Time ; Stack[top ++ ] = u ; Instack[u] = 1 ; for (int i = head[u] ; ~i ; i = edge[i].nex ){ int v = edge[i].to ; if(DFN[v] == -1) { tarjan(v , u) ; Low[u] = min(Low[u] ,Low[v]) ; if(DFN[u] < Low[v]) { edge[i].sign = 1;//为割桥 } } else if(Instack[v]) Low[u] = min(Low[u] ,DFN[v]) ; } if(Low[u] == DFN[u]){ int now; taj ++ ; bcc[taj].clear(); do{ now = Stack[-- top] ; Instack[now] = 0 ; Belong [now] = taj ; bcc[taj].push_back(now); }while(now != u) ; } } void tarjan_init(int all){ memset(DFN, -1, sizeof(DFN)); memset(Instack, 0, sizeof(Instack)); top = Time = taj = 0; for(int i=1;i<=all;i++)if(DFN[i]==-1 )tarjan(i, i); //注意开始点标!!! } vector
               
                G[N]; int du[N]; void suodian(){ for(int i = 1; i <= taj; i++)G[i].clear(), du[i] = 0; for(int i = 0; i < edgenum; i++){ int u = Belong[edge[i].from], v = Belong[edge[i].to]; if(u!=v)G[u].push_back(v), du[v]++; } } void init(){memset(head, -1, sizeof(head)); edgenum=0;} int dis[N]; int bfs(){ queue
                
                 q; for(int i = 1; i <= taj; i++) if(du[i]==0){q.push(i); dis[i] = bcc[i].size();} else dis[i] = 0; while(!q.empty()){ int u = q.front(); q.pop(); for(int i = 0; i < G[u].size(); i++){ int v = G[u][i]; dis[v] = max(dis[u]+(int)bcc[v].size(), dis[v]); du[v]--; if(du[v]==0) q.push(v); } } int ans = 1; for(int i = 1; i <= taj; i++)ans = max(ans, dis[i]); return ans; } int main() { int i,j,u,v; while(~scanf("%d %d",&n,&m)){ init(); while(m--){ scanf("%d %d",&u,&v); if(u!=v) add(u,v); } tarjan_init(n); suodian(); printf("%d\n",bfs()); } return 0; } /* 5 5 1 2 2 3 3 4 4 1 5 1 4 4 1 2 2 3 3 4 4 1 5 3 1 2 2 3 3 4 */ 
                
               
              
             
            
           
          
        
       
      
     
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇uva 10305 下一篇ZOJ 3792 Romantic Value 最小割..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: