2016 四川省赛F. Floyd-Warshall(LCA + brute force)
来源:互联网 发布:算法导论 附加部分答案 编辑:程序博客网 时间:2024/06/04 17:51
这是我第一次使用输入输出外挂,没错,第一次…….. 被卡成傻逼了.
题目链接
Floyd-Warshall
分析
题解icpc_camp 上面已经写的很清楚了.
https://post.icpc-camp.org/d/576-2016-hints
只需要将至多200个链接非树边的点离散出来,然后在对这两百个点做bfs找出以他们为起点的单元最短路就好了. 不过用并查集来找非树边会T成撒比,找了几份网上的代码,发现几乎都gg了
这里给一种不用并查集的做法,还记得双连通分量吗?用一个dfn 记录一下dfs序就好了,将环边拿出来.
不过我的码力太差了…..用了FAST IO 才过了
AC code
#include<bits/stdc++.h>#define pb push_back#define mp make_pair#define PI acos(-1)#define fi first#define se second#define INF 0x3f3f3f3f#define INF64 0x3f3f3f3f3f3f3f3f#define random(a,b) ((a)+rand()%((b)-(a)+1))#define ms(x,v) memset((x),(v),sizeof(x))#define eps 1e-8using namespace std;typedef unsigned long long ULL;typedef long long LL;typedef unsigned long long uLL;typedef long double DB;typedef pair<int,int> Pair;const int maxn = 1e5+10;const int MOD = 1e9+7;int num = 0;int dfs_clock = 0;Pair non_tree[300];std::vector<int> G[maxn];std::map<int, int> id;int tot =0;int idx[300];int dist[200+10][maxn];/*lca*/const int MAX_LOG = 18;int par[maxn][MAX_LOG];int dep[maxn];int dfn[maxn];void dfs(int u,int fa) { dep[u] =dep[fa]+1; dfn[u] = ++dfs_clock; par[u][0] = fa; for(auto v : G[u]){ if(!dfn[v])dfs(v,u); else if(v!=fa && dfn[v] < dfn[u])non_tree[num++] = mp(u,v); }}int lca(int u,int v){ if(dep[u]>dep[v])swap(u,v); for(int k = 0 ; k<MAX_LOG ; ++k){ if((dep[v] - dep[u]) & 1<<k) v = par[v][k]; } if(u==v)return v; for(int k = MAX_LOG -1; k>=0 ; --k){ if(par[u][k] != par[v][k]){ u = par[u][k]; v = par[v][k]; } } return par[u][0];}int vis[maxn];void bfs(int x) { int u = idx[x]; queue<int> Q; ms(vis,0); Q.push(u); dist[x][u] = 0; vis[u]=1; while (!Q.empty()) { u = Q.front();Q.pop(); for(auto v : G[u]){ if(!vis[v]){ vis[v] =1; dist[x][v] = dist[x][u]+1; Q.push(v); } } }}int Scan() { //输入外挂 int res = 0, flag = 0; char ch; if((ch = getchar()) == '-') flag = 1; else if(ch >= '0' && ch <= '9') res = ch - '0'; while((ch = getchar()) >= '0' && ch <= '9') res = res * 10 + (ch - '0'); return flag ? -res : res;}void Out(int a) { //输出外挂 if(a < 0) { putchar('-'); a = -a; } if(a >= 10) Out(a / 10); putchar(a % 10 + '0');}int main(){ // ios_base::sync_with_stdio(0); // cin.tie(0); // cout.tie(0); int n,m,q; n = Scan(); m = Scan(); q = Scan(); tot =0; num =0; dfs_clock = 0; while (m--) { int u,v; u = Scan();v = Scan(); G[u].pb(v); G[v].pb(u); } dfs(1,0); for(int k=1; k<MAX_LOG ; ++k){ for(int i=1 ; i<=n ; ++i)par[i][k] = par[par[i][k-1]][k-1]; } for(int i =0 ; i<num ; ++i){ int u = non_tree[i].fi,v = non_tree[i].se; // std::cout << u <<" non tree " << v << '\n'; if(!id.count(u)){ id[u] = tot++; idx[tot-1] = u; bfs(tot-1); } if(!id.count(v)){ id[v] = tot++; idx[tot-1] = v; bfs(tot-1); } } // std::cout << tot << '\n'; // for(auto e : id){ // std::cout << e.fi <<" " << e.se << '\n'; // } //for(int i=1 ; i<=n ; ++i)std::cout << dep[i] << '\n'; while (q--) { int u,v; u = Scan(); v = Scan(); int ans = dep[u]+dep[v] - 2*dep[lca(u,v)]; for(int i=0 ; i<tot ; ++i){ ans = min(ans, dist[i][u] + dist[i][v]); } Out(ans); putchar('\n'); } return 0;}
阅读全文
0 0
- 2016 四川省赛F. Floyd-Warshall(LCA + brute force)
- 2016四川省赛 Floyd-Warshall
- bnuoj52303 Floyd-Warshall(2016四川省赛)(生成树+倍增+SPFA)
- Brute Force
- Floyd-Warshall
- Floyd-Warshall
- Floyd-Warshall
- floyd-warshall
- Floyd-Warshall
- UESTC - 92 Journey(LCA)1012四川省赛
- Brute-Force算法实现
- brute force 汗一个
- Motif Search Brute Force
- 蛮力法(Brute Force)思想
- Brute-Force算法
- Brute force Attack
- md5 brute force hashcat
- DVWA之Brute Force
- 【矩阵快速幂+矩阵运算性质】Fast Matrix Calculation HDU
- SuperMarketSys超市管理系统(model2版本)
- centos服务器上mysql5.7.19数据库安装
- s5pv210-Linux驱动之USB-HOST主机控制器之EHCI
- Django URL传递参数的方法总结
- 2016 四川省赛F. Floyd-Warshall(LCA + brute force)
- 2-2 Time类的定义
- 监控ThreadPoolExecutor具体Task在Queue中等待时间
- Graduation Project Day 1
- 字符串反转(按单词正序输出),保留并打印所有空格。
- Openjudge 06:月度开销
- 一个斐波那契数列的前10项为:1, 2, 3, 5, 8, 13, 21, 34, 55, 89,对于一个最大项的值不超过n的斐波那契数列,求值为偶数的项的和。
- Codeforce Round #438 C.Bus(贪心)
- Mathematical Morphology —— Path Operator