2095: [Poi2010]Bridges

2024-03-27 04:58
文章标签 bridges 2095 poi2010

本文主要是介绍2095: [Poi2010]Bridges,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

混合图的欧拉回路一般解法:
二分 + 最大流
先二分,然后判断该图是否能构成欧拉回路
考虑欧拉回路的成立条件,入度等于出度
也就是说,对于有向边,只用考虑其对入度出度的贡献,
然后对于无向边就要考虑其方向…
那么先任意规定无向边的方向,然后跑最大流。
在满足没有点出入度为0或出入度差为奇数(因为此时改变无向边的方向出入度之差变化为2)的前提下
如果能满流,那么就成立,否则不成立
考虑为何这样是对的。。。
实际上一开始无向边规定的那一个流量1,相当于跑了以后出入度变化量为2,
所以s ->i的流量为(out-in)/2,i ->t的流量为(in-out)/2
所以跑最大流的过程实际上是把边的方向重新改变.
c++代码如下:

#include<bits/stdc++.h>
#define rep(i,x,y) for(register int i = x ; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T&x)
{x = 0;char c;int sign = 1;do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));x *= sign;
}const int N = 1e3+50,M = 4e5+500,inf = 1e9+7;
struct Str { int u,v,c,d; }edge[M];
int cur[N],head[N],nxt[M],to[M],f[M],tot;
int n,m,s,t,ans,d[N],in[N],out[N];inline void add(int x,int y,int w)
{f[tot] = w;to[tot] = y;nxt[tot] = head[x];head[x] = tot ++;
}inline bool bfs()
{queue<int>q ;memset(d,0,sizeof d);q.push(s); d[s] = 1;while(!q.empty()){int x = q.front();q.pop();cur[x] = head[x];for(register int i = head[x];~i;i = nxt[i])if(!d[to[i]] && f[i]){d[to[i]] = d[x] + 1;q.push(to[i]);}}return d[t];
}int dfs(int x,int w)
{if(x == t || !w) return w;int F,flow = 0;for(register int&i=cur[x];~i;i=nxt[i])if(d[to[i]] == d[x] + 1 && ( F = dfs(to[i],min(f[i],w)))){f[i] -= F;f[i^1] += F;w -= F; flow += F;if(!w) break;}return flow;    
}inline bool check(int x)
{memset(in,0,sizeof in);memset(out,0,sizeof out);memset(head,-1,sizeof head);tot = 0;rep(i,1,m){if(edge[i].c <= x){out[edge[i].v]++; in[edge[i].u]++;}else return false;if(edge[i].d <= x){add(edge[i].v,edge[i].u,1);add(edge[i].u,edge[i].v,0);}}int sum = 0,ans = 0;rep(i,1,n)if((abs(in[i] - out[i]) & 1) || (!in[i] && !out[i]))return false;else if(out[i] - in[i] > 0){add(s,i,(out[i] - in[i]) / 2);add(i,s,0);sum += (out[i] - in[i]) / 2;}else if(in[i] - out[i] > 0){add(i,t,(in[i] - out[i]) / 2);add(t,i,0);}while(bfs())ans += dfs(s,inf);return ans == sum;
}int main()
{read(n); read(m);rep(i,1,m){read(edge[i].u); read(edge[i].v);read(edge[i].c); read(edge[i].d);if(edge[i].c > edge[i].d)swap(edge[i].c,edge[i].d),swap(edge[i].u,edge[i].v);}s = 0;t = n + 1;int l = 1,r = 1e4+50,mid; while(l <= r){if(check(mid = l + r >> 1)) ans = mid,r = mid - 1;else l = mid + 1;}if(ans ) cout << ans << '\n';else puts("NIE");return 0;
}

这篇关于2095: [Poi2010]Bridges的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851002

相关文章

Aizu 2541 Magical Bridges

题意: n个岛屿,由m条桥连接,其中有k条是魔法桥,你可以用魔法把他们变成相同长度。 求在执行魔法后,两个起点S1和S2到终点T的最短路的最小绝对差。 (1≤n≤1000,1≤m≤2000,1≤k≤100) (1\leq n\leq 1000,1\leq m\leq 2000,1\leq k\leq 100) S1 S_1和 S2 S_2到 T T的最短路将会是如 j×x+disj\t

hdu 2095(1.2.5)

题目描述:find your present (2) Time Limit: 1000/2000 MS (Java/Others) Memory Limit: 32768/1024 K (Java/Others)Total Submission(s): 4105 Accepted Submission(s): 1224  Problem Description In the new year

hdu-2095-find your present (2)//1563-find your present

#include<stdio.h> int main() {     int n,i,t,m;     while(scanf("%d",&n)&&n)     {         scanf("%d",&t);         for(m=t,i=1;i<n;i++)         {             scanf("%d",&t);

POJ 2288 Islands and Bridges(状态压缩)

题目链接~~> 做题感悟:这题虽然看似很简单其实如果细心的话也不难,但是wa 了 n 次,wa 在了统计最优解个数上,开始没有开数组然后最后统计达到目标状态最优解的个数,这样是不对的,因为你只记录了最终的状态,可能在形成最优解的过程中有许多方法构成了最优解。 解题思路:                 (1) 、这题很容易想到状态方程 : dp[ S ^ (1<<k) ] [ j ] [ k

hdu_2095 find your present (2)

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2095 分析:              可以戳进去,看这里的分析。 我的代码: #include<stdio.h>int main(){int n;while(~scanf("%d",&n),n){int ans=0;for(int i=0;i<n;i++){int a;scanf("

BZOJ 2079 [Poi2010]Guilds 巧解

Description Zy皇帝面临一个严峻的问题,两个互相抵触的贸易团体,YYD工会和FSR工会,他们在同一时间请求在王国各个城市开办自己的办事处。这里有n个城市,其中有一些以双向马路相连,这两个工会要求每个城市应该做到: 1:有这个工会的办事处或 2:和另外一个符合1条件的城市有马路直接相连。(也就是每个城市必须是YYD的公会,但是又和FSR的公会的城市相连,或者是FSR的,和YYD的城市

LOJ #2483 [CEOI2017]Building Bridges CDQ分治+斜率优化

题目链接:传送门 洛咕传送门 令 s u m w sumw sumw表示 w w w的前缀和。 显然的 d p dp dp方程: d p [ i ] = m i n ( d p [ j ] + ( h [ i ] − h [ j ] ) 2 + s u m w [ i − 1 ] − s u m w [ j ] ) dp[i]=min(dp[j]+(h[i]-h[j])^2+sumw[i-1]-

E. Rudolf and k Bridges-Codeforces Round 933 (Div. 3)

E. Rudolf and k Bridges 这道题需要使用到deque deque:双端队列,可以在前后存取元素。 题目要求连续造k座桥,那么只需要把每一座桥的建造成本记录一下,最后取其中和最小的连续k座桥的成本即可。 对于每一座桥计算他的建造成本: 用dp来做,这座桥的第j个位置的建造成本为dp[j]; dp[j]=dp[k]+a[i][j]+1;其中k是一个范围[j-k-1,j-1];

HDUOJ 4738 Caocao‘s Bridges 题解 桥 割边 Tarjan

题目链接:HDUOJ 4738 Caocao’s Bridges 题目描述: 给定一个无向图,你可以选择最多删除一条边,删除边的代价是边的边权(特殊地,删除一条边权为0的边的代价是1),问最小代价使得图不连通。如果无论如何图都是连通的,那么则输出-1。 题解: 题目也就是需要我们求一条桥边,这个桥边所拥有的边权最小。我们只需要求出所有的桥边,然后对边权取一个最小值即可(需要注意边权为

[BZOJ 2096][Poi2010]Pilots:单调队列

点击这里查看原题 维护两个单调队列,一个递增,一个递减。 /*User:SmallLanguage:C++Problem No.:2096*/#include<bits/stdc++.h>#define ll long long#define inf 999999999using namespace std;const int M=3e6+5;int lx,rx,mx[M]