http://codeforces.com/contest/967/problem/F

题目大意:

有n个点,n*(n-1)/2条边的无向图,其中有m条路目前开启(即能走),剩下的都是关闭状态

定义:从x走到y(即x->y)后,和x所连接的边的所有状态都反转(即开启->关闭,关闭->开启)

问,从起点1走到终点n,最少需要经过几步,并且输出这个路径(如果存在多挑最短路径,输出任意一条)

如果不存在,则输出-1

思路:

其实这道题第一眼看过去就是bfs,不过,由于每个状态都在改变,那要怎么利用这个bfs的特性呢?

后来画了画图,你会发现,存在如下的问题。

对于一个a+1个点,b条边的图(其中终点,即a+1这个点是没有边连向它)来说,如果b=a*(a-1)/2,那么,无论如何都是走不到a+1这个点的。

所以,问题就转换成,如果b<a*(a-1)/2需要走几步。

于是我们可以发现,在b<a*(a-1)/2的情况中,我们又可以找出bb=aa*(aa-1)/2的情况。 其中bb表示b的子集,aa表示a的子集

于是不断剖析下去,最后只会得到两种情况

第一种:

a=3, b=2的情况(注,a=4才是终点,前面定义过了= =)

图形:①->②->③

即该情况步数是4步,即1->2->3->1->4

第二种:

a=4,  b=5的情况

(= =)一共4个点,告诉你边,你自己画吧

边为:

1 2

2 3

3 4

4 1

1 3

该情况步数是5

当然,可能存在步数<=4的情况,即从1出发直接按照题目所给边走到终点,这个就不用我说了吧!!!(具体为什么的话,请自己利用上面的两种情况分析一下)

所以根本不存在output中说的le6的情况

对于前面两种情况中,步数=4的情况是容易解决的,关键就是步数=5的情况容易TLE(= =,退役一年没做题,脑子锈逗了,T了一天)

首先我们可以发现步数=5的情况可以转移成——在删除起点1之后,步数=4的情况。

因此,我们只需要找一个从1->u的情况,设u包含u下面所有的子节点(不包含1)个数位C,那么如果该集合的节点个数(包含u)< u的边数,那么就存在解

解为1->u->v->z->u->n

然而= =,楼主先暴力u,再暴力v,再暴力z,T死我了

改成先暴力u,再暴力z,最后通过u、z找v就过了= =

原因是,因为你会发现,v满足的条件比z满足的条件要少,所以v的剪枝比较少,因此先暴力v所要判断的节点数目会更多,因此不优秀

(退役了以后做题是真的伤不起,还写得很麻烦= =,懒得优化了,自己看着办吧)

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 5e5 + ;
int n, m;
vector<int> G[maxn];
bool vis[maxn];
int pre[maxn]; bool bfs(int u){
queue<pair<int, int> > que;
que.push(mk(, ));
memset(pre, -, sizeof(pre));
vis[] = ;
while (!que.empty()){
pair<int, int> p = que.front(); que.pop();
int u = p.fi, step = p.se;
//if (u == n) break;
for (int i = ; i < G[u].size(); i++){
int v = G[u][i];
if (vis[v]) continue;
vis[v] = true;
pre[v] = u;
if (step + <= ){
que.push(mk(v, step+));
}
}
}
while(!que.empty()) que.pop();
if (pre[n] == -) return false;
int pos = n;
vector<int> ans; ans.pb(pos);
while (pre[pos] != -){
ans.pb(pre[pos]);
pos = pre[pos];
}
reverse(ALL(ans));
if (ans.size() > ) return false;
printf("%d\n", ans.size()-);
for (int i = ; i < ans.size(); i++)
printf("%d ", ans[i]);
cout << endl;
return true;
} void display(int a, int b, int c, int d, int e, int f){
printf("5\n%d %d %d %d %d %d\n", a, b, c, d, e, f);
} void bfs2(int x, vector<int> &cache){
vis[x] = ;
queue<int> que;
que.push(x);
cache.pb(x);
while (!que.empty()){
int u = que.front(); que.pop();
for (int i = ; i < G[u].size(); i++){
if (vis[G[u][i]] || u == )continue;
vis[G[u][i]] = ;
que.push(G[u][i]);
cache.pb(G[u][i]);
}
}
} set<int> mys[maxn];
int main(){
cin >> n >> m;
for (int i = ;i <= m; i++){
int u, v; scanf("%d%d", &u, &v);
G[u].pb(v), G[v].pb(u);
mys[u].insert(v); mys[v].insert(u);
}
if (m == ) return puts("-1"), ;
if (n == ) return printf("1\n1\n"), ;
//direct from 1 to n
if (bfs()) return ;
memset(vis, , sizeof(vis));
//other(just 4 steps) for (int i = ; i < G[].size(); i++){//the next point which connect to 1
vis[G[][i]] = ;
}
for (int i = ; i < G[].size(); i++){
int u = G[][i];
for (int j = ; j < G[u].size(); j++){
int v = G[u][j];
if (v == || vis[v]) continue;
printf("4\n1 %d %d 1 %d\n", u, v, n);
return ;
}
}
//other(just 5 steps)
//1->u->v->z->u->n
memset(vis, , sizeof(vis));
vector<int> cache;
for (int i = ; i < G[].size(); i++){
int u = G[][i];
if (vis[u]) continue;
cache.clear();
bfs2(u, cache);
if (G[u].size() < cache.size()){
for (int j = ; j < cache.size(); j++){
u = cache[j];
if (!mys[u].count()) continue;
if (G[u].size() >= cache.size()) continue;
for (int k = ; k < G[].size(); k++){
int z = G[][k];
if (!vis[z] || mys[z].count(u) || z == u) continue;
if (G[z].size() >= cache.size()) continue;
for (int f = ; f < G[z].size(); f++){
int v = G[z][f];
if (!mys[v].count() || !mys[v].count(u)) continue;
if (v == ) continue;
display(, u, v, z, u, n);
return ;
}
} }
}
}
puts("-1");
return ;
} /*
5 5
1 2
2 3
3 4
4 1
1 3
*/

Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) F 构造的更多相关文章

  1. Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) E 贪心

    http://codeforces.com/contest/967/problem/E 题目大意: 给你一个数组a,a的长度为n 定义:b(i) = a(1)^a(2)^......^a(i), 问, ...

  2. Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) D 贪心

    http://codeforces.com/contest/967/problem/D 题目大意: 有n个服务器,标号为1~n,每个服务器有C[i]个资源.现在,有两个任务需要同时进行,令他为x1,x ...

  3. 【枚举】【二分】Codeforces Round #477 (rated, Div. 2, based on VK Cup 2018 Round 3) D. Resource Distribution

    题意:有两个服务要求被满足,服务S1要求x1数量的资源,S2要求x2数量的资源.有n个服务器来提供资源,第i台能提供a[i]的资源.当你选择一定数量的服务器来为某个服务提供资源后,资源需求会等量地分担 ...

  4. Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)A. Protect Sheep

    http://codeforces.com/contest/948/problem/A   A. Protect Sheep Bob is a farmer. He has a large pastu ...

  5. Codeforces Round #470 (rated, Div. 1, based on VK Cup 2018 Round 1) 923D 947D 948E D. Picking Strings

    题: OvO http://codeforces.com/contest/947/problem/D 923D 947D 948E 解: 记要改变的串为 P1 ,记目标串为 P2  由变化规则可得: ...

  6. Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1) C.Producing Snow

    题目链接  题意  每天有体积为Vi的一堆雪,所有存在的雪每天都会融化Ti体积,求出每天具体融化的雪的体积数. 分析 对于第i天的雪堆,不妨假设其从一开始就存在,那么它的初始体积就为V[i]+T[1. ...

  7. 【推导】【贪心】Codeforces Round #472 (rated, Div. 2, based on VK Cup 2018 Round 2) D. Riverside Curio

    题意:海平面每天高度会变化,一个人会在每天海平面的位置刻下一道痕迹(如果当前位置没有已经刻划过的痕迹),并且记录下当天比海平面高的痕迹有多少条,记为a[i].让你最小化每天比海平面低的痕迹条数之和. ...

  8. 【推导】Codeforces Round #472 (rated, Div. 2, based on VK Cup 2018 Round 2) B. Mystical Mosaic

    题意:给你一个棋盘的最终局面. 你的一次操作可以选择一些行和列,将它们的交叉点染黑,不能重复选择某行或者某列.问你是否能经过数次操作之后,达到目标局面. 就枚举所有黑点,如果该点行列都没被标记,就给它 ...

  9. Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1)

    A. Protect Sheep time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

随机推荐

  1. mvc5.0-路由

    :first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdow ...

  2. (功能篇)回顾Bug管理系统Mantis优化改造经历

    共分为两篇,功能篇和技术篇. 时间大约是2016年冬天. 考虑搭一个用于Bug管理和追踪的系统. 综合比较下,选择了小巧的开源工具,Mantis. 在源码基础上,做代码修改,完成了定制版的优化改造. ...

  3. Github pages + Minimal-Mistakes + Disqus建立个人博客记录

    本文详细记录了利用Github pages建立个人博客的步骤. github pages官方推荐使用Jekyll生成静态网页,jekyll支持各种不同的主题,Minimal-Mistakes是一个功能 ...

  4. 转载别人的一篇关于git的文章

    转载网址:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

  5. JWT总结

    Json web token (JWT) 什么是JWT? Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该toke ...

  6. PAT甲题题解-1030. Travel Plan (30)-最短路+输出路径

    模板题最短路+输出路径如果最短路不唯一,输出cost最小的 #include <iostream> #include <cstdio> #include <algorit ...

  7. 评审other's意见

    评审意见 1.组 a.界面不友好 b.没连数据库 2.组 a.没连数据库 b.无智能匹配当前时间 3.组 a.基本功能实现 b.界面未优化 4.组 ourselves 5.组 a.各反面较为完善 6. ...

  8. 铁大快捷记账Alpha版使用说明书

    一. 引言 (1) 编写目的 (2) 参考资料 (3) 术语和缩写词 二. 网站概述 (1) 网站用途 (2) 网站运行 三. 网站使用过程 (1)网站登录 (2) 功能说明 一.引言 (1)编写目的 ...

  9. jqgrid查找

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletExcepti ...

  10. Android开发环境(发展演变)

    初步接触android,要安装android开发工具时是使用eclipse,这是因为百度靠前的搜索项是eclipse来开 发android,而且那时还不知道android studio. 首先是下载配 ...