设为首页 加入收藏

TOP

BZOJ 2561 最小生成树 网络流 最小割
2015-07-20 17:33:55 来源: 作者: 【 】 浏览:1
Tags:BZOJ 2561 最小 生成 网络

题目大意:给出一个图,每个边有权值。最后再给一条边。问最少去掉多少条边,可以使得这条新加的边既可能出现在最小生成树中,有可能出现在最大生成树中。


思路:先考虑最小生成树(最大的也一样)。若想这条边出现在最小生成树中,那么比这条边边权小的边一定不能将这条边的两点连起来,否则就不会选择这条边。所以就将所有的边权比这条边小的边建图,然后泡最小割,使得这两给点不连起来。这就是满足去掉最少的边让它出现在最小生成树。最大生成树就在建一张图,然后答案累加,就可以了。


CODE:


#include 
  
   
#include 
   
     #include 
    
      #include 
     
       #include 
      
        #define MAX 400010 #define INF 0x7f7f7f7f #define S (add.x) #define T (add.y) using namespace std; struct Complex{ int x,y; int length; bool operator <(const Complex &a)const { return length < a.length; } void Read() { scanf("%d%d%d",&x,&y,&length); } }edge[MAX],add; int points,edges; int head[MAX],total = 1; int _next[MAX],aim[MAX],flow[MAX]; int ans; int deep[MAX]; inline void Add(int x,int y,int f); void Initialize(); bool BFS(); int Dinic(int x,int f); int main() { cin >> points >> edges; for(int i = 1;i <= edges; ++i) edge[i].Read(); add.Read(); sort(edge + 1,edge + edges + 1); for(int i = 1;edge[i].length < add.length; ++i) { Add(edge[i].x,edge[i].y,1); Add(edge[i].y,edge[i].x,1); } while(BFS()) ans += Dinic(S,INF); Initialize(); int start = 1; while(edge[start].length <= add.length) start++; for(int i = start;i <= edges; ++i) { Add(edge[i].x,edge[i].y,1); Add(edge[i].y,edge[i].x,1); } while(BFS()) ans += Dinic(S,INF); cout << ans << endl; return 0; } inline void Add(int x,int y,int f) { _next[++total] = head[x]; aim[total] = y; flow[total] = f; head[x] = total; } void Initialize() { total = 1; memset(head,0,sizeof(head)); } bool BFS() { static queue
       
         q; while(!q.empty()) q.pop(); memset(deep,0,sizeof(deep)); deep[S] = 1; q.push(S); while(!q.empty()) { int x = q.front(); q.pop(); for(int i = head[x];i;i = _next[i]) if(!deep[aim[i]] && flow[i]) { deep[aim[i]] = deep[x] + 1; q.push(aim[i]); if(aim[i] == T) return true; } } return false; } int Dinic(int x,int f) { if(x == T) return f; int temp = f; for(int i = head[x];i;i = _next[i]) if(deep[aim[i]] == deep[x] + 1 && flow[i] && temp) { int away = Dinic(aim[i],min(flow[i],temp)); flow[i] -= away; flow[i^1] += away; temp -= away; } return f - temp; }
       
      
     
    
   
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Codeforces 385 C Bear and Prime.. 下一篇HDU 1950 Bridging signals (DP)

评论

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

·PostgreSQL 索引 - (2025-12-25 22:20:43)
·MySQL Node.js 连接 (2025-12-25 22:20:41)
·SQL 撤销索引、表以 (2025-12-25 22:20:38)
·Linux系统简介 (2025-12-25 21:55:25)
·Linux安装MySQL过程 (2025-12-25 21:55:22)