小明的阁楼

故事再美 结局还是再见


  • 首页

  • 归档

  • 标签

  • 搜索

luogu1268 树的重量

发表于 2018-04-25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
好题啊
看了半天不会
去看题解
妙啊
还是不明白
重点就是不知道为什么树的重量是一定的
而做法就相当于证明一样
每加上去一个点,相当于从一对点的路径上伸出来一条边
看题解时发现一个有趣的结论
根据两两点之间的最短距离建出的树应该都是同构的(边权均非负)
然而应该不是同构
每次选最小的值w(i,j)
若存在k,使得w(i,k)+w(k,j)=w(i,j),则i,j之间不需要连边
否则就连边
这样应该可以确定一个边数最少的图
在这个图上填一写较大的边(大于两端点的最短距离)不会产生任何影响
阅读全文 »

十年磨一剑

发表于 2018-04-23

阅读全文 »

luogu1462 通往奥格瑞玛的道路

发表于 2018-04-23
1
2
3
4
5
很久没写最短路了
题目有点绕
看懂之后就是一个二分
dijk在开O2下比spfa快(正常也应该快啊。。)
deque更快的(O2下,可queue居然是最快的。。)
阅读全文 »

luogu1341 无序字母对

发表于 2018-04-23
1
2
3
4
5
欧拉回路
注意图可能不连通(尽管数据没卡)
要求字典序最小的欧拉回路
所以要用邻接矩阵
注意要倒序输出
阅读全文 »

【学习笔记】欧拉路&哈密顿路

发表于 2018-04-22
1
2
3
4
5
6
7
8
9
10
```
<!--more-->
欧拉路:
- 1.存在性判断:
无向图:无奇点等价于欧拉回路;有两个奇点等价于欧拉通路
有向图:所有点的入度都等于出度等价于存在欧拉回路;一个点入度比出度多1,另一个点出度比入度多1等价于欧拉通路
- 2.fleury算法:
DFS(u):
    While (u存在未被删除的边e(u,v))
        删除边e(u,v)
        DFS(v)
    End
    PathSize ← PathSize + 1
    Path[ PathSize ] ← u
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
注意有向图的欧拉路要倒序输出
[很好的资料](http://www.cnblogs.com/TheRoadToTheGold/p/8439160.html)
哈密顿路(np问题):
- 1.狄拉克定理:如果图G是一个具有$n(n\geq 3)$个顶点的简单无向图,并且图G中每个顶点的度数至少为$n/2$,那么图G是哈密顿图(具有哈密顿回路的图)。(证明:归纳)
奥勒定理(dirac定理的推广):如果图G是一个具有$n(n\geq 3)$个顶点的简单无向图,并且图G中每一对不相邻的顶点u和v满足$deg(u)+deg(v)\geq n$,那么图G是哈密顿图。
- 2.n(n>=2)阶竞赛图一定存在哈密顿通路。(证明:归纳)
当且仅当竞赛图是强连通的,存在哈密顿回路。(证明:归纳)
- 3.竞赛图上的哈密顿回路
先找到一个环,再在环上扩展。
hdu3414
#include<iostream> #include<cstdio> #include<cstring> #include<climits> #include<queue> #include<bitset> #define mp make_pair #define pb push_back using namespace std; typedef long long LL; typedef pair<int,int> PII; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } const int N=1008; int n; int a[N][N]; int nxt[N]; bool vis[N]; bool flag; int cnt; inline bool dfs(int x) { vis[x]=1; if(a[x][1]){ nxt[x]=1; ++cnt; return 1; } for(int i=2;i<=n;++i){ if(!vis[i]&&a[x][i]){ if(dfs(i)){ nxt[x]=i; ++cnt; return 1; } } } return 0; } inline void solve() { memset(nxt,0,sizeof(nxt)); memset(vis,0,sizeof(vis)); cnt=0; if(!dfs(1)){ puts("-1"); return; } while(1){ flag=0; for(int i=2;i<=n;++i){ if(!nxt[i]){ for(int j=1;j<=n;++j){ if(nxt[j]&&a[j][i]&&a[i][nxt[j]]){ nxt[i]=nxt[j]; nxt[j]=i; ++cnt; flag=1; break; } } } } if(!flag){ break; } } if(cnt==n){ printf("1"); for(int i=nxt[1];i!=1;i=nxt[i]){ printf(" %d",i); } puts(""); } else{ puts("-1"); } } int main() { while(1){ scanf("%d",&n); if(!n) return 0; for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j){ a[i][j]=read(); } } if(n==1){ puts("1"); continue; } solve(); } return 0; } ```

打鱼记

发表于 2018-04-22
1
梦游~
阅读全文 »

未命名

发表于 2018-04-22

kd-tree
n个k维空间下的点
复杂度O($n^{(k-1)/k}$)

阅读全文 »

luogu1415 拆分数列

发表于 2018-04-20
1
2
f[i]表示从前往后到i时,最后一个数为f[i]-i(a-b表示从第a位到第b位),满足数列严格递增的f[i]的最大值
g[i]表示从后往前到i时,最后一个数为i-g[i],满足数列严格递增的g[i]的最大值
阅读全文 »

luogu1070 道路游戏

发表于 2018-04-20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
dp
f[i]表示到i时刻的最大收益
sum[k][j]表示第k个机器人前j时间的收益
f[i]=max(f[j]+sum[k][i]-sum[k][j]-a[getid(k+j)];
其中a[]的下标应该是从k往后走j步的地方
记得把f[]初始化成最小的,答案可能是负的
这样O($n^3$)就能过了(毕竟pj题)
2d/1d考虑优化成2d/0d
单调队列
i不好放到单调队列里
j有限制(j>=i-p),j应该是单调队列的一个下标
然而一维并不好处理这个问题
q[k][j]表示对每个k的一个单调队列
max(f[j]-sum[k][j]-a[getid(k+j)]->q[k][j]
这样对每个i只需要枚举k
跑了100+ms
然而candy?的代码20+ms
但他的代码中有一点问题
过不了hack
f[i][j]中最大不一定是最好(有后效性)
因为step[i][j]=p时,是无法向后转移的
阅读全文 »

luogu2051 [AHOI2009]中国象棋

发表于 2018-04-18
1
2
3
4
5
f[i][j][k]表示到第i行,其中j列有1个,k列有2个
转移见代码
不要把n和m打错了!!!
不要把n和m打错了!!!
不要把n和m打错了!!!
阅读全文 »
1…789…12
littleming

littleming

112 日志
57 标签

© 2002 - 2019 littleming
由 Hexo 强力驱动
主题 - NexT.Muse
总访问量次 | 总访客人 |