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. stl源码剖析 详细学习笔记deque(1)

    //--------------------------15/3/12---------------------------- deque { deque没有容量(capacity)观念,是动态分段的 ...

  2. Redux系列x:源码解析

    写在前面 redux的源码很简洁,除了applyMiddleware比较绕难以理解外,大部分还是 这里假设读者对redux有一定了解,就不科普redux的概念和API啥的啦,这部分建议直接看官方文档. ...

  3. 用信鸽来讲解HTTPS的知识

    加密是一个很难理解的东西,这里头满是数学证明.不过,除非你是在开发一个加密系统,否则无需了解那些高阶的复杂知识. 如果你看这篇文章是为了创造下一个 HTTPS 协议,很抱歉,请出门左走,鸽子是远远不够 ...

  4. Netty源码分析(前言, 概述及目录)

    Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...

  5. Docker swarm集群搭建教程

    一.什么是Swarm Swarm这个项目名称特别贴切.在Wiki的解释中,Swarm behavior是指动物的群集行为.比如我们常见的蜂群,鱼群,秋天往南飞的雁群都可以称作Swarm behavio ...

  6. 区块链扩容方案之Gas值限制

    区块链扩容一直是区块链团队的重点研究方向.因为比特币对区块大小的设定是固定的,而且中本聪将最初大小值限定为1M,但随着交易量的增加,网络拥堵情况也愈渐严重,最终也导致了比特币的分叉. 区别于比特币固定 ...

  7. 《口算大作战 2》DLC:算法真奇妙

    211614331 王诚荣 211614354 陈斌 --第一次结对作业 DLC DLC:三年级混合运算模块现已更新!现在您可以愉快的使用三年级题库啦.同时您必须拥有本体才能使用此DLC 单击此处查看 ...

  8. Java实验报告(实验二)

    课程:Java程序设计          班级: 1351 姓名:王玮怡                学号:20135116 成绩:             指导教师:娄嘉鹏       实验日期: ...

  9. 20135202闫佳歆--week4 系统调用(上)--学习笔记

    此为个人笔记存档 week 4 系统调用(上) 一.用户态.内核态和中断处理过程 用户通过库函数与系统调用联系起来. 1.内核态 在高执行级别下,代码可以执行特权指令,访问任意的物理地址. 2.用户态 ...

  10. 《实时控制软件设计》之Automation Studio开发环境

    Automation Studio是贝加莱公司的控制软件开发平台,软件可运行在贝加莱的基于PC的控制器上,基于Automation Studio我们可构建一个完整的控制软件构建.测试和仿真运行平台.本 ...