zoukankan      html  css  js  c++  java
  • 洛谷 P3931 SAC E#1

    题目背景

    冴月麟和魏潇承是好朋友。

    题目描述

    冴月麟为了守护幻想乡,而制造了幻想乡的倒影,将真实的幻想乡封印了。任何人都无法进入真实的幻想乡了,但是她给前来救她的魏潇承留了一个线索。

    她设置了一棵树(有根)。树的每一条边上具有割掉该边的代价。

    魏潇承需要计算出割开这棵树的最小代价,这就是冴月麟和魏潇承约定的小秘密。

    帮帮魏潇承吧。

    注:所谓割开一棵有根树,就是删除若干条边,使得任何任何叶子节点和根节点不连通。

    输入输出格式

    输入格式:

    输入第一行两个整数(n)(S)表示树的节点个数和根。

    接下来(n-1)行每行三个整数(a、b、c),表示(a、b)之间有一条代价为(c)的边。

    输出格式:

    输出包含一行,一个整数,表示所求最小代价。

    输入输出样例

    输入样例#1:

    4 1
    1 2 1 
    1 3 1
    1 4 1
    

    输出样例#1:

    3
    

    输入样例#2:

    4 1
    1 2 3
    2 3 1
    3 4 2
    

    输出样例#2:

    1
    

    说明

    对于(20\%)的数据,(n <= 10)

    对于(50\%)的数据,(n <= 1000)

    对于(100\%)的数据,(n <= 100000)

    思路:还是个最小割问题,那么就对应的用最大流做法。每一条边都对应的一个权值, 对其建立网络流模型,跑一遍(dinic)算法就是答案。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<queue>
    #define maxn 1000007
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,S,T,rt,head[maxn],num=1,d[maxn];
    inline int qread() {
      char c=getchar();int num=0,f=1;
      for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
      for(;isdigit(c);c=getchar()) num=num*10+c-'0';
      return num*f;
    }
    struct node {
      int v,w,nxt;
    }e[maxn<<2];
    inline void ct(int u, int v, int w) {
      e[++num].v=v;
      e[num].w=w;
      e[num].nxt=head[u];
      head[u]=num;
    }
    void Dfs(int u, int fa) {
      int f=0;
      for(int i=head[u];i;i=e[i].nxt) {
      	int v=e[i].v;
      	if(v!=fa) {
      	  f=1;
    	  Dfs(v,u);	
    	}
      }
      if(!f) {
      	ct(u,T,inf);
      	ct(T,u,inf);
      }
    }
    inline bool bfs() {
      memset(d,-1,sizeof(d));
      queue<int>q;
      q.push(S),d[S]=0;
      while(!q.empty()) {
      	int u=q.front();
      	q.pop();
      	for(int i=head[u];i;i=e[i].nxt) {
      	  int v=e[i].v;
      	  if(e[i].w&&d[v]==-1) {
      	    d[v]=d[u]+1;
    		q.push(v);	
    	  }
    	}
      }
      return d[T]!=-1;
    }
    int dfs(int u, int f) {
      if(u==T) return f;
      int rest=f;
      for(int i=head[u];i;i=e[i].nxt) {
      	int v=e[i].v;
      	if(d[v]==d[u]+1&&e[i].w&&rest) {
      	  int t=dfs(v,min(e[i].w,rest));
    	  if(!t) d[v]=0;
    	  e[i].w-=t;
    	  e[i^1].w+=t;
    	  rest-=t;
    	}
      }
      return f-rest;
    }
    inline int dinic() {
      int ans=0;
      while(bfs()) ans+=dfs(S,inf);
      return ans;
    }
    int main() {
      n=qread(),rt=qread();
      S=rt,T=n+1;
      for(int i=1,u,v,w;i<n;++i) {
      	u=qread(),v=qread(),w=qread();
      	ct(u,v,w),ct(v,u,w);
      }
      Dfs(rt,0);
      printf("%d
    ",dinic());
      return 0;
    }
    
  • 相关阅读:
    172. Factorial Trailing Zeroes
    96. Unique Binary Search Trees
    95. Unique Binary Search Trees II
    91. Decode Ways
    LeetCode 328 奇偶链表
    LeetCode 72 编辑距离
    LeetCode 226 翻转二叉树
    LeetCode 79单词搜索
    LeetCode 198 打家劫舍
    LeetCode 504 七进制数
  • 原文地址:https://www.cnblogs.com/grcyh/p/10804257.html
Copyright © 2011-2022 走看看