Lyz's Blog

Never Give Up

概述

考试时太浮躁!不要心急打程序,一定要静下心来仔细思考算法。是否可行(时限能否过)。保证思考算法的时间。对于自己熟练地算法,要相信能想得出来就一定能最快的调出来。根据数据范围,大胆猜测考得是什么算法。有时候直接想暴力是不科学的,暴力有时非常的复杂,还会带乱对整道题的思绪。
对一些普通算法的应用还不够了解,看不出一道题考察的是什么算法。平时训练要多一些对算法的思考,能不看题解就不看题解,花多点时间在思考上。
DAY1

开考时有点小紧张,看到T1题目很长,就更紧张了!!!
T1:仔细读题,纯暴力。打完用了半个小时,又打了一个判断正确性的程序拍了一下,花了1个多小时,耗时较大,拖慢了后面的解题时间。

T2:紧张依旧挥之不去,随手画了个图,发现是找一个最小的环,然后就想到了tarjan缩点。就开打了。到了最后才发现,tarjan会爆栈,然而为时已晚。
考试时要及时测试小数据和大数据,不要嫌麻烦而只出随机数据。尽管大部分时候程序可以在随机数据下面表现良好。
考试时要冷静下来,仔细思考算法是否存在漏洞。

阅读全文 »

tarjan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;

const int N = 100000+10, M = 1000000+10;
int ans[N],e[2][N],rd[N],next[2][M],to[2][M],v[N],h[N];
int dfn[N],low[N],col[N],stack[N],sum[N],f[N],tot[2];
bool p[N],instack[N];
int n,m,k,Index,top,ctot;

bool cmp(int x,int y) {return x>y;}

void add(int x,int y,int kind)
{
tot[kind] ++;
to[kind][tot[kind]] = y;
next[kind][tot[kind]] = e[kind][x];
e[kind][x] = tot[kind];
}

int gf(int x)
{
if (x!=h[x]) h[x] = gf(h[x]);
return h[x];
}

void link(int x,int y)
{
int i=gf(x), j=gf(y);
if (i!=j) h[i]=j;
}

void tarjan(int x,int kind)
{
dfn[x] = low[x] = ++ Index;
instack[x] = 1;
stack[++ top] = x;
for (int i=e[kind][x];i;i=next[kind][i])
{
int y = to[kind][i];
if (col[y]) continue;
if (instack[y]) low[x] = min(low[x],dfn[y]);
else {tarjan(y,kind);low[x]=min(low[x],low[y]);}
}
if (dfn[x]==low[x])
{
int y;
ctot ++;
do
{
y = stack[top --];
instack[y] = 0;
sum[ctot] += v[y];
col[y] = ctot;
} while (y!=x);
}
}

void work(int x,int kind)
{
p[x] = 1;
f[x] += sum[x];
for (int i=e[kind][x];i;i=next[kind][i])
{
int y = to[kind][i];
link(x,y);
rd[y] --;
f[y] = max(f[y],f[x]);
if (rd[y]==0) work(y,kind);
}

}

int main()
{
freopen("azeroth.in","r",stdin);
freopen("azeroth.out","w",stdout);


scanf("%d%d",&n,&m);
for (int i=1;i<=m;i ++)
{
int u,v;
scanf("%d%d",&u,&v);
if (u==v) continue;
add(u,v,0);
}
for (int i=1;i<=n;i ++) scanf("%d",&v[i]);
scanf("%d",&k);

for (int i=1;i<=n;i ++) if (!col[i]) tarjan(i,0);


for (int j=1;j<=n;j ++)
for (int i=e[0][j];i;i=next[0][i])
{
int u = j,v = to[0][i];
if (col[u]!=col[v])
{
add(col[u],col[v],1);
rd[col[v]] ++;
}
}
//构造新图
for (int i=1;i<=ctot;i ++) h[i] = i;
for (int i=1;i<=ctot;i ++)
if (rd[i] == 0 && !p[i])
work(i,1);
for (int i=1;i<=ctot;i ++)
{
ans[gf(i)] = max(ans[gf(i)],f[i]);
}
sort(ans+1,ans+1+ctot,cmp);
for (int i=1;i<=min(k+1,ctot);i ++)
ans[0] += ans[i];
printf("%d\n",ans[0]);

return 0;
}

拓扑排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;

const int N = 1000000+5,M = 1000000+5;
struct node
{
int y,next;
} h[M];
int n,m,tot,l,r;
int e[N],list[N],rd[N];

void add(int x,int y)
{
tot ++;
h[tot].y = y;
h[tot].next = e[x];
e[x] = tot;
rd[y] ++;
}

int main()
{
freopen("mikado.in","r",stdin);
freopen("mikado.out","w",stdout);

scanf("%d%d",&n,&m);
for (int i=1;i<=m;i ++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
}
l = 1;r = 0;
for (int i=1;i<=n;i ++)
if (!rd[i]) list[++ r] = i;
while (l<=r)
{
int now = list[l ++];
for (int i=e[now];i;i=h[i].next)
{
int y = h[i].y;
rd[y] --;
if (!rd[y]) list[++ r] = y;
}
}
printf("%d\n",r);

return 0;
}
阅读全文 »

  中缀表达式的求值问题是一个比较常见的问题之一,我们通常在编写程序时,直接写出表达式让编译器去处理,很少去关心编译器是怎么对表达式进行求值的,今天我们来一起了解一下其中具体的原理和过程。

  表达式一般来说有三种:前缀表达式、中缀表达式、后缀表达式,其中后缀表达式又叫做逆波兰表达式。中缀表达式是最符合人们思维方式的一种表达式,顾名思义,就是操作符在操作数的中间。而前缀表达式和后缀表达式中操作符分别在操作数的前面和操作数的后面。举个例子:

  3+2

  这个是最简单的一个中缀表达式。而其等同的前缀表达式形式为+32,后缀表达式形式为32+。

阅读全文 »

10.30晚

概述
一定要用心想算法,在没想清楚之前,不要轻易打程序,不然后面耗的时间会更多

第一题:没有细想,直接上暴力。发现暴力跑的挺快的,只有在某些特殊数据下跑的比较慢。要是细想不难发现规律,但还是有很多小细节需要注意。

第二题:打了一个非常恶心的暴力,没有细致计算时间复杂度,最后发现好像连30%的数据都过不去。于是看了看数据范围,反过来想考察算法的时间复杂度。最后想到正解了。本来正解是对的,但因为题目描述和自己理解的一点偏差,将正解改成和暴力一样是错的了。
下次一定要认真细致的看题!!!

阅读全文 »

概述

今天这套题做的还好,只是一开始题目意思比较难以理解。
****
T1:Ocd

第一题看了半天都没看明白。最后通过样例数据和猜测,明白了题目的意思。
并没有什么太好的方法,打了个暴力本来想着应该过40%的数据,最后过了70%。正解也不是特别难想。
****
T2:Mancity

没有特别好的方法,一步一步走暴力
****
T3:Captcha

阅读全文 »
0%