正题

题目链接:https://loj.ac/p/2460


题目大意

给出nnn个点mmm条边的一张无向图,每条边双向的权值不同,求一条经过的最大权值最小的欧拉回路。

2≤n≤1000,1≤m≤200002\leq n\leq 1000,1\leq m\leq 200002≤n≤1000,1≤m≤20000


解题思路

显然我们可以二分答案,考虑二分答案后我们怎么做。

不妨设权值小的那个方向为默认方向,那这样我们可以处理出一个入度-出度的数组degdegdeg。

此时我们翻转一条边可以让头的degdegdeg移动222到尾处,那么做法就很显然了。

如果度数有奇数直接无解,否则我们用网络流连接能翻转的边去配平degdegdeg。

得到一个答案后我们就可以根据残余网络得到一张有欧拉回路的有向图了。

然后就是有向图的欧拉回路,发现我们如果随机走一条路出去的话此时可能会走到死路。

但是注意到如果一个位置是死路那么之前我们肯定来过至少一次这里。那么做法就是我们正常的遍历没有走过的边,到死路时我们回退回去,类似于正常的dfsdfsdfs可以继续搜其他的路。

此时我们就可以合并我们伸出的两条路,反过来记录和输出遍历的边就好了


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#define mp(x,y) make_pair(x,y)
using namespace std;
const int M=2e4+1e3,N=1e3+10;
int n,m,s,t,tot,S,fa[N],p[M];
int deg[N],ls[N],dep[N];
queue<int> q;stack<int> st;
queue<pair<int,int> >G[N];
struct edge{int to,next,w;
}a[M*4];
struct node{int x,y,w;
}e[M];
void addl(int x,int y,int w){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w;a[++tot].to=x;a[tot].next=ls[y];ls[y]=tot;a[tot].w=0;return;
}
bool bfs(){while(!q.empty())q.pop();q.push(s);memset(dep,0,sizeof(dep));dep[s]=1;while(!q.empty()){int x=q.front();q.pop();for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(!a[i].w||dep[y])continue;dep[y]=dep[x]+1;if(y==t)return 1;q.push(y);}}return 0;
}
int dinic(int x,int flow){if(x==t)return flow;int rest=0,k;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(dep[x]+1==dep[y]&&a[i].w){rest+=(k=dinic(y,min(a[i].w,flow-rest)));a[i].w-=k;a[i^1].w+=k;if(rest==flow)return rest;}}if(!rest)dep[x]=0;return rest;
}
int find(int x)
{return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
int check(int w){memset(ls,0,sizeof(ls));tot=1;for(int i=1;i<=n;i++){if(deg[i]>0)addl(s,i,deg[i]/2);if(deg[i]<0)addl(i,t,-deg[i]/2);}for(int i=1;i<=m;i++)if(e[i].w<=w)addl(e[i].x,e[i].y,1),p[i]=tot;int ans=0;while(bfs())ans+=dinic(s,1e9);return (ans==S);
}
void dfs(int x){while(!G[x].empty()){int y=G[x].front().first;int k=G[x].front().second;G[x].pop();dfs(y);st.push(k);}return;
}
int main()
{//  freopen("euler.in","r",stdin);
//  freopen("euler.out","w",stdout);scanf("%d%d",&n,&m);s=n+1;t=n+2;for(int i=1;i<=n;i++)fa[i]=i;int k=n,L=0,R=0;for(int i=1;i<=m;i++){int x,y,v1,v2;scanf("%d%d%d%d",&x,&y,&v1,&v2);if(v1>v2)swap(x,y),swap(v1,v2);if(find(x)!=find(y))fa[find(x)]=find(y),k--;L=max(L,v1);R=max(R,v2);e[i]=(node){y,x,v2};deg[x]--;deg[y]++;}if(k!=1)return puts("NIE")&0;for(int i=1;i<=n;i++)if(deg[i]&1)return puts("NIE")&0;else if(deg[i]>0) S+=deg[i]/2;int lim=R;while(L<=R){int mid=(L+R)>>1;if(check(mid))R=mid-1;else L=mid+1;}if(L>lim)return puts("NIE")&0;check(L);printf("%d\n",L);for(int i=1;i<=m;i++){if(e[i].w<=L){if(a[p[i]].w)G[e[i].x].push(mp(e[i].y,i));else G[e[i].y].push(mp(e[i].x,i));}else G[e[i].y].push(mp(e[i].x,i));}dfs(1);while(!st.empty())printf("%d ",st.top()),st.pop();return 0;
}

Loj#2460-「POI2010」桥Bridges【网络流,欧拉回路】相关推荐

  1. @loj - 2483@「CEOI2017」Building Bridges

    目录 @desription@ @solution@ @accepted code@ @details@ @desription@ 有 n 根柱子依次排列,第 i 根柱子的高度为 hi .现可以花费 ...

  2. LOJ#2427. 「POI2010」珍珠项链 Beads

    题目地址 题目链接 题解 不会算复杂度真是致命,暴力枚举k每次计算是n/2+n/3+n/4+...+1的,用调和级数算是\(O(nlogn)\)的... 如果写哈希表的话能够\(O(nlogn)\), ...

  3. Loj #3111. 「SDOI2019」染色

    Loj #3111. 「SDOI2019」染色 题目描述 给定 \(2 \times n\) 的格点图.其中一些结点有着已知的颜色,其余的结点还没有被染色.一个合法的染色方案不允许相邻结点有相同的染色 ...

  4. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  5. LOJ#2230. 「BJOI2014」大融合

    LOJ#2230. 「BJOI2014」大融合 题目描述 小强要在$N$个孤立的星球上建立起一套通信系统.这套通信系统就是连接$N$个点的一个树.这个树的边是一条一条添加上去的. 在某个时刻,一条边的 ...

  6. loj#2143. 「SHOI2017」组合数问题

    loj#2143. 「SHOI2017」组合数问题 题目描述 Solution 考虑转化一下我们要求的东西. ∑i=0n(nkik+r)=∑i=0n(nki)[i≡r(modk)]\sum_{i=0} ...

  7. LOJ#2542. 「PKUWC2018」随机游走

    LOJ#2542. 「PKUWC2018」随机游走 题目描述 Solution 去过一个点集中所有节点的期望时间不好求,考虑min−maxmin-maxmin−max容斥,转化为求第一次到达某一个点集 ...

  8. LOJ#2145. 「SHOI2017」分手是祝愿

    LOJ#2145. 「SHOI2017」分手是祝愿 题目描述 Solution 首先有一个结论: 灯的状态序列a1,a2...ana_1,a_2...a_na1​,a2​...an​唯一对应了一个最优 ...

  9. Loj #2568. 「APIO2016」烟花表演

    Loj #2568. 「APIO2016」烟花表演 题目描述 烟花表演是最引人注目的节日活动之一.在表演中,所有的烟花必须同时爆炸.为了确保安全,烟花被安置在远离开关的位置上,通过一些导火索与开关相连 ...

  10. Loj #2585. 「APIO2018」新家

    Loj #2585. 「APIO2018」新家 题目描述 五福街是一条笔直的道路,这条道路可以看成一个数轴,街上每个建筑物的坐标都可以用一个整数来表示.小明是一位时光旅行者,他知道在这条街上,在过去现 ...

最新文章

  1. MySql 中锁的定义
  2. MySQL拷贝表的几种方式
  3. mysql 修复表 阿里云_MySql数据表修复方法-阿里云开发者社区
  4. SpringBoot无法找到加载类 ,应用Feign其他服务无法package两类问题
  5. redisb并发访问慢出现的问题
  6. easyui-combobox 模糊匹配 支持汉字和拼音_巧用数据验证制作模糊匹配的下拉列表...
  7. Linux环境下实现一个简单socket通信
  8. 毕业设计--MySqL的初探
  9. 李雅普诺夫稳定性理论的理解
  10. C++程序设计案例实训教程第6章
  11. 节假日查询接口,加班,补班,日期查询,放假,日历
  12. aptana手动配置python环境_Python学习1:使用Aptana构建Python开发环境
  13. c/c++ 头文件(.h)、源文件(.cpp)书写及接口与实现分离实例
  14. QT用QWidget做的气泡聊天功能,可发图片、文件、文本等气泡信息,功能简单,适合初学者
  15. 一、YouTube-8M 初探(视频与音频分类)
  16. epson喷墨一体机打印照片偏色的调整
  17. R实战 | OPLS-DA(正交偏最小二乘判别分析)筛选差异变量(VIP)及其可视化
  18. Kup Buty Under Armour także czynników bocznych
  19. 《代号:魂之刃2》- 身处黑暗的勇者游戏
  20. 震惊!某程序员吐槽零基础自学编程很难,真的是这样吗?

热门文章

  1. 计算机视觉招聘_INDEMIND|SLAM、计算机视觉、深度学习算法招聘(社招实习)
  2. curd什么意思中文_每日一句英译英:She's a ten什么意思?
  3. linux安装卷管理,Linux安装管理ISCSI卷(initiator端)
  4. java如何用键盘输入_java中如何从键盘输入(附代码)
  5. java emoji编码转换_java转换emoji表情
  6. make: *** 没有规则可制作目标“distclean”。 停止。_Makefile伪目标
  7. s2 安恒 漏洞验证工具_Struts2漏洞利用工具下载(更新2017-V1.8版增加S2-045/S2-046)
  8. 如何区分netty是udp还是tcp_鲜奶粉还是大包粉,到底该如何区分?
  9. excel怎么设置打印区域_别再浪费打印纸了!这样设置,Excel表格再大都能打印成一页!...
  10. JAVA中小细节(易忽视和易错点)