GDSOI2015的某道题目




分析:
看到这个$3^i$就觉得很奇怪的样子...为什么一定要是$3^i$...而且不能重复使用...
不能重复使用就代表不会产生进位,那么一定是若干个$3^i$相加减的式子...
仔细观察,我们发现这是一个最短路径的问题,每个技能就是一条有向边,考虑要求能够用其他技能组合出来当前的技能,也就是说找到一条路径使得从当前技能的$a$出发不经过当前技能的那条边回到当前技能的$b$...这样就是说我们需要求出从每个点出发走向每个点的最短路和次短路,要求最短路和次短路的第一条边不相同...就可得到答案了...
有一个需要特别注意的点就是出现$a_i=b_i$的情况要特判一下...
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
//by NeighThorn
#define inf 0x3f3f3f3f
using namespace std; const int maxn=1600+5,maxm=20000+5; int n,m,a[maxm],b[maxm],c[maxm],ans[maxm],del[maxm];
int cnt,w[maxm],hd[maxn],to[maxm],nxt[maxm],vis[maxn];
int dis[maxn][2],from[maxn][2]; inline void add(int x,int y,int s){
w[cnt]=s;to[cnt]=y;nxt[cnt]=hd[x];hd[x]=cnt++;
} inline void spfa(int x){
memset(del,0,sizeof(del));
memset(dis,inf,sizeof(dis));
memset(from,inf,sizeof(from));
queue<int> q;dis[x][0]=dis[x][1]=0;
for(int i=hd[x];i!=-1;i=nxt[i]){
if(dis[to[i]][0]>w[i]) dis[to[i]][1]=dis[to[i]][0],from[to[i]][1]=from[to[i]][0],dis[to[i]][0]=w[i],from[to[i]][0]=i;
else if(dis[to[i]][1]>w[i]) dis[to[i]][1]=w[i],from[to[i]][1]=i;
del[i]=1;
if(!vis[to[i]])
q.push(to[i]),vis[to[i]]=1;
}
while(!q.empty()){
int top=q.front();q.pop();vis[top]=0;
for(int i=hd[top],modi;i!=-1;i=nxt[i])
if(!del[i]){
modi=0;
if(dis[top][0]+w[i]<dis[to[i]][0]){
modi=1;
if(from[to[i]][0]!=from[top][0]){
dis[to[i]][1]=dis[to[i]][0],from[to[i]][1]=from[to[i]][0];
dis[to[i]][0]=dis[top][0]+w[i],from[to[i]][0]=from[top][0];
}
else
dis[to[i]][0]=dis[top][0]+w[i];
}
else if(dis[to[i]][1]>dis[top][0]+w[i]&&from[to[i]][0]!=from[top][0])
modi=1,dis[to[i]][1]=dis[top][0]+w[i],from[to[i]][1]=from[top][0];
if(dis[to[i]][1]>dis[top][1]+w[i]&&from[to[i]][0]!=from[top][1])
modi=1,dis[to[i]][1]=dis[top][1]+w[i],from[to[i]][1]=from[top][1];
if(modi&&!vis[to[i]])
vis[to[i]]=1,q.push(to[i]);
}
}
for(int i=hd[x];i!=-1;i=nxt[i])
ans[i]=from[to[i]][0]==i?dis[to[i]][1]:dis[to[i]][0];
} signed main(void){
freopen("A.in","r",stdin);
freopen("A.out","w",stdout);
memset(hd,-1,sizeof(hd));
scanf("%d%d",&n,&m);cnt=1;
for(int i=1;i<=m;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]),add(a[i],b[i]+n,c[i]);
for(int i=1;i<=n;i++) add(i+n,i,0);
for(int i=1;i<=n;i++) spfa(i);
for(int i=1;i<=m;i++) printf("%d\n",ans[i]==inf?-1:ans[i]);
return 0;
}
By NeighThorn
GDSOI2015的某道题目的更多相关文章
- C语言超级经典400道题目
C语言超级经典400道题目 1.C语言程序的基本单位是____ A) 程序行 B) 语句 C) 函数 D) 字符.C.1 2.C语言程序的三种基本结构是____构A.顺序结构,选择结构,循环结 B.递 ...
- hdu 动态规划(46道题目)倾情奉献~ 【只提供思路与状态转移方程】(转)
HDU 动态规划(46道题目)倾情奉献~ [只提供思路与状态转移方程] Robberies http://acm.hdu.edu.cn/showproblem.php?pid=2955 背包 ...
- 小白欢乐多——记ssctf的几道题目
小白欢乐多--记ssctf的几道题目 二哥说过来自乌云,回归乌云.Web400来源于此,应当回归于此,有不足的地方欢迎指出. 0x00 Web200 先不急着提web400,让我们先来看看web200 ...
- 在 n 道题目中挑选一些使得所有人对题目的掌握情况不超过一半。
Snark and Philip are preparing the problemset for the upcoming pre-qualification round for semi-quar ...
- SQL的几道题目
1.构造数据插入方案表t_project_finish表 a)将addtime更新为当前时间的前一天 首先想到的是addtime=addtime-1,然后就开始验证这个想法. 插入一行数据,包括主键和 ...
- codeforces 几道题目
BZOJ挂了....明天就要出发去GDKOI了....不能弃疗. 于是在cf水了几道题, 写写详(jian)细(dan)题解, 攒攒RP, 希望GDKOI能好好发挥....... 620E. New ...
- GDOI2015的某道题目
分析: 考试的时候由于一些神奇的原因(我就不说是什么了)...没有想$C$题,直接交了个暴力上去... 然后发现暴力的数组开的太大,由于矩阵乘法的需要做$m$次初始化,所以只拿到了10分... 我们一 ...
- leetcode 几道题目
是周六晚上的几道题,晚上11点半,睡的早,起不来! 494. Target Sum 分析:看完这题,看到数据范围,长度20,枚举就是1<<20 = 1e6, 然后单次20,总共就是2e8, ...
- C++面试出现频率最高的30道题目
http://blog.csdn.net/wangshihui512/article/details/9092439 1.new.delete.malloc.free关系 delete会调用对象的析构 ...
随机推荐
- Sphinx与coreseek
Sphinx : 高性能SQL全文检索引擎 分类 编程技术 Sphinx是一款基于SQL的高性能全文检索引擎,Sphinx的性能在众多全文检索引擎中也是数一数二的,利用Sphinx,我们可以完成比数据 ...
- centos7下安装oracle11gR2的详细步骤
环境准备 安装包: CentOS-7-x86_64-DVD linux.x64_11gR2_database_1of2.zip linux.x64_11gR2_database_2of2.zip 本教 ...
- erc20代币合约
看这篇文章需要对以太坊,智能合约,代币等概念有基本的了解. 什么是ERC20 可以把ERC20简单理解成以太坊上的一个代币协议,所有基于以太坊开发的代币合约都遵守这个协议.遵守这些协议的代币我们可以认 ...
- MongoDB复制二:复制集的管理
1.修改oplog的大小 需要在每个机器上都配置.先在secondary上操作,最后在primary上操作. 1)以单机的方式重启复制集的实例 db.shutdownServer() 在新的端口中启 ...
- Java IO流-File类的使用示例-创建文件夹和文件的正确方法
当创建一个文件时,比如:E:\\test\\test.txt,此时若文件夹test不存在,那么直接创建文件会出错,故首先要判断文件夹是否存在,不存在的话要首先创建文件夹. public class F ...
- 【iOS开发】iOS开发CGRectGetMidX. CGRectGetMidY.CGRectGetMinY. CGRectGetMaxY. CGRectGetMinX. CGRectGetMaxX的使用
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, 10, 110, 150)]; label.backgroundColor ...
- 转---详细的Android开发环境搭建教程
五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程 引言 在windows安装Android的开发环境不简单也说不上算复杂,本文写给第一次想在自己Windows上建立A ...
- PokeCats开发者日志(七)
现在是PokeCats游戏开发的第十二天的晚上,很不幸提交到的三个平台(360开放平台,腾讯开放平台,华为应用市场)都没通过,著作权申请也被打回来了. 心中一万只草泥马在奔腾. 得了,看来 ...
- PHP+AJAX 实现表格实时编辑
https://blog.csdn.net/qq_29627497/article/details/81365107 源码链接:https://pan.baidu.com/s/1fAinVXU-nWt ...
- P2127 序列排序
题目描述 小C有一个N个数的整数序列,这个序列的中的数两两不同.小C每次可以交换序列中的任意两个数,代价为这两个数之和.小C希望将整个序列升序排序,问小C需要的最小代价是多少? 输入输出格式 输入格式 ...