bzoj 2561

这题表面上看上去有些无从下手。。但只需去掉所给边为最大(小)的环就可以了

然后要挑出比所给边大(小)的边建图找最小割即可

要把最大和最小生成树分开做(一开始想一起合着做但这图明显不对呀)

 1 #include<bits/stdc++.h>
 2 #define inc(i,l,r) for(int i=l;i<=r;i++)
 3 #define dec(i,l,r) for(int i=l;i>=r;i--)
 4 #define link(x) for(edge *j=h[x];j;j=j->next)
 5 #define mem(a) memset(a,0,sizeof(a))
 6 #define inf 1e9
 7 #define ll long long
 8 #define succ(x) (1<<x)
 9 #define nm 800000+5
10 #define NM 20000+5
11 using namespace std;
12 int read(){
13     int x=0,f=1;char ch=getchar();
14     while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
15     while(isdigit(ch))x=x*10+ch-‘0‘,ch=getchar();
16     return x*f;
17 }
18 struct edge{
19     int t,v;
20     edge *next,*rev;
21 }e[nm],*h[NM],*p=e;
22 void _add(int x,int y,int v){
23     p->t=y;p->v=v;p->next=h[x];h[x]=p;p++;
24 }
25 void add(int x,int y,int v){
26     _add(x,y,v);_add(y,x,0);
27     h[x]->rev=h[y];h[y]->rev=h[x];
28 }
29 int n,m,S,T,_t,l[nm],r[nm],dis[nm],d[NM],k,ans;
30 bool v[NM];
31 queue<int >q;
32 int bfs(){
33     mem(v);mem(d);
34     v[S]++;d[S]++;q.push(S);
35     while(!q.empty()){
36         int t=q.front();q.pop();
37         link(t)
38         if(j->v&&(!d[j->t]||d[j->t]>d[t]+1)){
39             d[j->t]=d[t]+1;
40             if(!v[j->t])v[j->t]++,q.push(j->t);
41         }
42     }
43     return d[T];
44 }
45 int dfs(int x,int k){
46     int _a;
47     if(x==T)return k;
48     link(x)
49     if(j->v&&d[j->t]==d[x]+1&&(_a=dfs(j->t,min(j->v,k)))){
50         j->v-=_a;j->rev->v+=_a;return _a;
51     }
52     return 0;
53 }
54 int main(){
55 //    freopen("data.in","r",stdin);
56     n=read();m=read();
57     inc(i,1,m){
58         l[i]=read();r[i]=read();dis[i]=read();
59     }
60     S=read();T=read();k=read();
61     inc(i,1,m)
62     if(dis[i]>k)add(l[i],r[i],1),add(r[i],l[i],1);
63     while(bfs())
64     if(_t=dfs(S,inf))ans+=_t;
65     p=e;mem(h);
66     inc(i,1,m)
67     if(dis[i]<k)add(l[i],r[i],1),add(r[i],l[i],1);
68     while(bfs())
69     if(_t=dfs(S,inf))ans+=_t;
70     printf("%d\n",ans);
71     return 0;
72 }

时间: 2024-10-11 19:12:15

bzoj 2561的相关文章

BZOJ 2561 最小生成树(最大流)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2561 题意:给定一个边带正权的连通无向图G= (V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最少多少条边,才能够使得这条边既可能出现在最小生成树上,也可能出现在最大生成树 上? 思路:考虑克鲁斯卡尔算法的过程.若加入的 边(u,v,L)能够出现在最小生成树中,那么权值小于L的边

BZOJ 2561 最小生成树 | 网络流 最小割

链接 BZOJ 2561 题解 用Kruskal算法的思路来考虑,边(u, v, L)可能出现在最小生成树上,就是说对于所有边权小于L的边,u和v不能连通,即求最小割: 对于最大生成树的情况也一样.容易看出两个子问题是各自独立的,把两个最小割相加即可. #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <queue> using

BZOJ 2561: 最小生成树(最小割)

U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------------------------- #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<que

BZOJ 2561 最小生成树 【最大流】

Description 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最少多少条边,才能够使得这条边既可能出现在最小生成树上,也可能出现在最大生成树上? Solution 题意:在一个图中,问一条边即在最小生成树上,又在最大生成树上需要从图上删掉多少条边 在最小生成树上,一条边不被选择的充要条件是什么呢? 当比它小的边已经将它所连接的两点连接起来的时候,这

BZOJ 2561: 最小生成树【最小割/最大流】

Description 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最少多少条边,才能够使得这条边既可能出现在最小生成树上,也可能出现在最大生成树上? Input 第一行包含用空格隔开的两个整数,分别为N和M: 接下来M行,每行包含三个正整数u,v和w表示图G存在一条边权为w的边(u,v). 最后一行包含用空格隔开的三个整数,分别为u,v,和 L: 数据

BZOJ 2561 最小生成树

第一眼瞎那啥贪心,然后觉得不太对劲,就滚去看题解,发现是网络流OTZ 模拟Kruskal的过程发现,若<u,v>要在最小生成树中出现,权值则小于<u,v>的边不能让u,v联通,转换成最小割模型,最大生成树同理. 跑两遍最大流. 注意边要建双向的啊,被这点坑死了.然后板子不要瞎那啥乱打. 顺便发现果然ISAP跑得很快. //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #i

bzoj 2561: 最小生成树【最小割】

看错题了以为多组询问吓得不行-- 其实还挺好想的,就是数据范围一点都不网络流.把U作为s,V作为t,以最小生成树为例,(U,V,L)要在最小生成树上,就要求所有边权比L小的边不能连通(U,V)所在的联通块.这样一来模型就很显然了,就是对所有边权<L的边建边(u,v,1)(v,u,1),然后最小割即可.建双向边是因为反正只会割掉一条-- #include<iostream> #include<cstdio> #include<cstring> #include<

【BZOJ】【2561】最小生成树

网络流/最小割 对于所有小于L的边求一个割使得U,V不连通,这样就可以保证L可能在最小生成树里. 最大生成树同理. 答案累加一下即可.(Orz Hzwer) (我一开始怎么会sb地去想到一起求呢……) 1 /************************************************************** 2 Problem: 2561 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:884 ms 7 Me

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max