bzoj 2561: 最小生成树

最小割,,,用比L小的搞到最小生成树,然最小割一下,那么在加上L后就会使图联通变为树,就可以了。最大同理,答案加起来

 1 #include<bits/stdc++.h>
 2 #define N 200005
 3 #define LL long long
 4 #define inf 0x3f3f3f3f
 5 #define ls tr[x][0]
 6 #define rs tr[x][1]
 7 using namespace std;
 8 inline int ra()
 9 {
10     int x=0,f=1; char ch=getchar();
11     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
12     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
13     return x*f;
14 }
15 struct node{
16     int to,next,v;
17 }e[N<<3];
18 int head[N],cnt=1;
19 struct data{
20     int x,y,v;
21 }a[N];
22 int h[N],q[N<<3],U,V,L,ans,n,m;
23 void in(int x, int y, int v)
24 {
25     e[++cnt].to=y; e[cnt].v=v; e[cnt].next=head[x]; head[x]=cnt;
26 }
27 void insert(int x, int y, int v)
28 {
29     in(x,y,v); in(y,x,1); //双向边2333 
30 }
31 bool bfs()
32 {
33     for (int i=1; i<=n; i++) h[i]=-1;
34     h[U]=0; q[0]=U; int l=0,r=1;
35     while (l<r)
36     {
37         int x=q[l++];
38         for (int i=head[x];i;i=e[i].next)
39             if (h[e[i].to]==-1 && e[i].v)
40             {
41                 h[e[i].to]=h[x]+1;
42                 q[r++]=e[i].to;
43             }
44     }
45     if (h[V]==-1) return 0;
46     return 1;
47 }
48 int dfs(int x, int f)
49 {
50     if (x==V) return f;
51     int used=0,w;
52     for (int i=head[x];i;i=e[i].next)
53         if (e[i].v && h[e[i].to]==h[x]+1)
54         {
55             w=dfs(e[i].to,min(f-used,e[i].v));
56             used+=w; e[i].v-=w; e[i^1].v+=w;
57             if (used==f) return f;
58         }
59     if (!used) h[x]=-1;
60     return used;
61 }
62 void dinic() {while (bfs()) ans+=dfs(U,inf);}
63 bool cmp(data a, data b)
64 {
65     return a.v<b.v;
66 }
67 int main()
68 {
69     n=ra(); m=ra();
70     for (int i=1; i<=m; i++)
71         a[i].x=ra(),a[i].y=ra(),a[i].v=ra();
72     sort(a+1,a+m+1,cmp);
73     U=ra(),V=ra(),L=ra();
74     for (int i=1; i<=m; i++)
75         if (a[i].v<L) insert(a[i].x,a[i].y,1);
76         else break;
77     dinic(); cnt=1;
78     memset(head,0,sizeof(head));
79     for (int i=m; i>=1; i--)
80         if (a[i].v>L) insert(a[i].x,a[i].y,1);
81         else break;
82     dinic(); cout<<ans;
83     return 0;
84 }

 

posted @ 2017-03-01 08:17  ws_ccd  阅读(116)  评论(0编辑  收藏  举报