Freda的烦恼
CF原题http://codeforces.com/contest/215/problem/D
贪心,只租一辆或者让所有人不要求赔偿。花费关于满载车辆是一个一次函数,题目相当于一次函数在一个区间里求最大值。
Code type Pointer1=^node1; node1=record v:integer; data:char; next:Pointer1; end; Pointer2=^node2; node2=record v:integer; next:Pointer2; end; var e:array[1..100] of Pointer1; map:array[1..100,'A'..'z'] of Pointer2; Q,s,t,n,m,i,ans:longint; c,ttt:char; a:array[1..100] of integer; procedure build(s,t:longint;c:char); var P:Pointer1; begin new(p);p^.v:=t;p^.data:=c;p^.next:=e[s];e[s]:=p;end; procedure add(s:longint;c:char;t:longint); var q:Pointer2; begin new(q);q^.v:=t;q^.next:=map[s][c];map[s][c]:=q;end; procedure BFS(x,y:integer):boolean; var begin h:=0;t:=1;Que[1]:=x; end; begin assign(input,'trav.in'); assign(output,'trav.out'); reset(input);rewrite(output); readln(N,M);ans:=maxlongint; for i:=1 to M do begin readln(s,t,ttt,c); build(s,t,c); add(t,c,s); end; readln(Q); for i:=1 to q do read(a[i]); for i:=1 to q-1 do begin ans:=maxlongint; BFS(a[i],a[i+1],0); if ans<>maxlongint then writeln(ans) else writeln('-1'); end; close(input);close(output); end.
Freda的迷宫
std是求桥,有人说LCA暴力可过。明天学一下这俩东西。
学过Tarjan发明的算法的都说Tarjan神。。。一次DFS遍历能求桥求割点求LCA,代码差不多,连并查集都跟他有关系,太厉害了。
两点间有唯一路径等价于两点间在原图中任意路径上不存在非桥边,所以我们把桥找到,然后在新的图中只保留桥,利用并查集判断两点间连通性。这里具体实现利用边是否访问过来保证拓扑。
Code uses math; const Max_N=10000; Max_M=100000; var v,next:array[1..Max_M*2] of longint; DFN,LOW,Adjlist,father:array[1..Max_N] of longint; InS:array[1..Max_N] of boolean; bridge,vis:array[1..Max_M] of boolean; l,r:array[1..Max_M] of longint; tot,i,m,n,q,Index,x,y:longint; procedure build(x,y:integer); begin inc(tot);v[tot]:=y; next[tot]:=Adjlist[x]; Adjlist[x]:=tot; end; function find(x:longint):longint; begin if father[x]=x then exit(x); father[x]:=find(father[x]); find:=father[x]; end; procedure union(x,y:longint); begin father[find(x)]:=find(y);end; procedure Tarjan(u:longint); var i:longint; begin inc(Index); DFN[u]:=Index; LOW[u]:=Index; InS[u]:=true; i:=Adjlist[u]; while i<>0 do begin if not vis[i>>1] then begin vis[i>>1]:=true; if DFN[v[i]]=0 then begin Tarjan(v[i]); LOW[u]:=min(LOW[u],LOW[v[i]]); if DFN[u]<LOW[v[i]] then bridge[i>>1]:=true; end else begin if InS[v[i]] then LOW[u]:=min(DFN[v[i]],LOW[u]); end; end; i:=next[i]; end; InS[u]:=false; end; begin readln(n,m,q);tot:=1; for i:=1 to n do father[i]:=i; for i:=1 to m do begin readln(l[i],r[i]); build(l[i],r[i]); build(r[i],l[i]); end; for i:=1 to n do if DFN[i]=0 then Tarjan(i); for i:=1 to N do if bridge[i] then union(l[i],r[i]); for i:=1 to Q do begin readln(x,y); if find(x)=find(y) then writeln('Y') else writeln('N'); end; end.
Freda的旗帜
我写了个暴力,得了10分,囧。。。
单纯DP只有80分。居然有每种颜色都最多只有一种颜色能接的数据,这种O(1)算答案,还是DP就TLE了。方程不难,考试居然没想到。最近DP做的少,题目总是往图论和贪心上想。
方程F[i][j]=sigma(F[i-1][k])(A[j][k]=true);G[i]=sigma(f[j][k])(j=1..i,k=1..c)
Code var s:string; j,k,count:longint; A:array[1..10,1..10] of boolean; ans,i,g,n,c:Qword; d:array[1..10] of longint; f1,f2:array[1..10] of qword; f:boolean; function UPint(x:real):qword; begin UPint:=trunc(x); if x>trunc(x) then inc(UPint); end; begin readln(n,c); for j:=1 to c do begin readln(s); for k:=1 to c do if s[k]='1' then begin A[j][k]:=true; inc(d[j]); end; end; f:=true; for j:=1 to c do begin if d[j]>1 then f:=false; if d[j]>0 then inc(count); end; if f then begin dec(n,c); ans:=1; inc(ans,UPint(n/count)); writeln(ans); halt; end; for j:=1 to c do f1[j]:=1; g:=c;i:=2; while i<=n do begin for j:=1 to c do begin for k:=1 to c do if A[j][k]then inc(f2[j],f1[k]); inc(G,f2[j]); if G>=n then begin writeln(i); halt; end; end; f1:=f2;fillchar(f2,sizeof(f2),0); i:=i+1; end; end.
总结
110分75名,这次名次好低啊。我应该写第二题暴力,唉。还是应该注意不能AC就写部分数据。毕竟noip分数线去年不到400,也就是说一次模拟赛A掉第一题,二三题加起来能的一百分就行了。学会骗分。