终于上橙了...说起来有点小意外..本来看不会做打算用小号做Div.2的,然后我开错浏览器交到大号了...造成的结果就是拿命去调试B.幸好最后过了
【AC代码见题解最下方】
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
A.Mr. Kitayuta, the Treasure Hunter
有30001个岛屿,0到30000。你从0出发,给你第一次跳的距离d。若某次跳的距离为k,则以后每次都只能跳k+1,k,k-1。某些岛屿有宝藏。问你遵照跳跃规则,最多可以拿到多少宝藏。
当时抱着反正做了A也会掉分的心态所以没做。其实就是个水DP。我们用f[i][j]表示在第i的位置,跳的距离是d+j。注意到这里j的范围很小。-300到+300就可以。【最多只能变换那么多次】因为j可以是负数我们可以整体加上300。然后直接转移即可
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
问你最多加入多少条有向边才可以满足所有的m对关系。
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int f[30001][1001];
int a[30001];
inline int max(int x,int y)
{
if(x>y)
return x;
return y;
}
int main()
{
int n,d;
scanf("%d%d",&n,&d);
int x;
int i,j;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
a[x]++;
}
for(i=0;i<=30000;i++)
for(j=0;j<=600;j++)
f[i][j]=-2100000000;
f[d][300]=a[d];
for(i=d+1;i<=30000;i++)
{
for(j=1;j<=599;j++)
{
if(i-(d+j-300)>=0&&(d+j-300)>0)
{
f[i][j]=max(max(f[i-(d+j-300)][j],f[i-(d+j-300)][j+1]),f[i-(d+j-300)][j-1])+a[i];
/* if(j-1>=0)
f[i][j]=max(f[i-(d+j-300)][j-1],f[i][j]);
f[i][j]+=a[i];*/
}
}
}
int ans=a[d];
for(i=1;i<=30000;i++)
for(j=0;j<=600;j++)
ans=max(f[i][j],ans);
printf("%d\n",ans);
return 0;
}
B. Mr. Kitayuta's Technology:
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int edge;
int head[300001];
int scc,cnt;
bool v[300001];
int s[400001],top;
int dfn[400001],low[400001],belong[400001];
int indeg[400001],outdeg[400001],sdeg[400001];
struct map
{
int s,t;
int next;
}a[300001];
inline void add(int s,int t)
{
a[edge].next=head[s];
head[s]=edge;
a[edge].s=s;
a[edge].t=t;
}
inline void tarjan(int d)
{
int i,x;
cnt++;
dfn[d]=cnt;
low[d]=cnt;
top++;
s[top]=d;
v[d]=true;
for(i=head[d];i!=0;i=a[i].next)
{
x=a[i].t;
if(dfn[x]==0)
{
tarjan(x);
low[d]=min(low[d],low[x]);
}
else if(v[x]&&low[d]>dfn[x])
low[d]=dfn[x];
}
if(dfn[d]==low[d])
{
scc++;
x=s[top];
top--;
while(x!=d)
{
v[x]=false;
belong[x]=scc;
x=s[top];
top--;
}
v[x]=false;
belong[x]=scc;
}
}
inline void count_edge()
{
int i,j,d;
for(i=1;i<=n;i++)
sdeg[belong[i]]++;
}
int father[400001];
int sx[400001];
inline int find(int x)
{
if(father[x]!=x)
father[x]=find(father[x]);
return father[x];
}
inline int count_edgeex()
{
int i,j,d;
int fx,fy;
int s=0;
for(i=1;i<=n;i++)
{
for(j=head[i];j!=0;j=a[j].next)
{
d=a[j].t;
fx=find(belong[i]);
fy=find(belong[d]);
if(fx!=fy)
{
if(sx[fx]==1||sx[fy]==1)
s++;
father[fx]=fy;
if(sx[fx]!=1||sx[fy]!=1)
{
sx[fx]+=sx[fy];
sx[fy]=sx[fx];
}
}
}
}
return s;
}
int main()
{
int m;
scanf("%d%d",&n,&m);
int i;
int s,t;
for(i=1;i<=m;i++)
{
scanf("%d%d",&s,&t);
edge++;
add(s,t);
}
for(i=1;i<=n;i++)
if(!belong[i])
tarjan(i);
count_edge();
for(i=1;i<=scc;i++)
{
father[i]=i;
sx[i]=sdeg[i];
}
int ans=0;
for(i=1;i<=scc;i++)
if(sdeg[i]!=1)
ans+=sdeg[i];
ans+=count_edgeex();
/*if(ans>n)
ans=n;*/
printf("%d\n",ans);
return 0;
}
D. Mr. Kitayuta's Colorful Graph:
#include<map>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
map <pair<int,int>,int> st;
struct line
{
int s,t,c;
}a[200001];
struct ask
{
int u,v;
int x;
}ans[200001];
inline bool cmp(line x,line y)
{
if(x.c<y.c)
return true;
return false;
}
int fa[200001];
inline int find(int x)
{
if(fa[x]==0)
{
fa[x]=x;
return fa[x];
}
if(fa[x]!=x)
fa[x]=find(fa[x]);
return fa[x];
}
int sx[200001];
bool v[200001];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int i,j,k,t;
for(i=1;i<=m;i++)
scanf("%d%d%d",&a[i].s,&a[i].t,&a[i].c);
sort(a+1,a+1+m,cmp);
int q;
scanf("%d",&q);
for(i=1;i<=q;i++)
scanf("%d%d",&ans[i].u,&ans[i].v);
int td=sqrt(m);
int fx,fy;
for(i=1;i<=m;i++)
{
for(j=i+1;j<=m;j++)
if(a[j].c!=a[i].c)
break;
j--;
//for(k=1;k<=n;k++)
// fa[k]=k;
memset(fa,0,sizeof(fa));
if(j-i+1>td)
{
for(k=i;k<=j;k++)
{
fx=find(a[k].s);
fy=find(a[k].t);
if(fx!=fy)
fa[fx]=fy;
}
for(k=1;k<=q;k++)
{
fx=find(ans[k].u);
fy=find(ans[k].v);
if(fx==fy)
ans[k].x++;
}
}
else
{
int p=0;
memset(v,false,sizeof(v));
for(k=i;k<=j;k++)
{
fx=find(a[k].s);
if(!v[a[k].s])
{
p++;
sx[p]=a[k].s;
v[a[k].s]=true;
}
fy=find(a[k].t);
if(!v[a[k].t])
{
p++;
sx[p]=a[k].t;
v[a[k].t]=true;
}
if(fx!=fy)
fa[fx]=fy;
}
for(k=1;k<=p;k++)
{
for(t=k+1;t<=p;t++)
{
if(sx[k]!=sx[t])
{
fx=find(sx[k]);
fy=find(sx[t]);
if(fx==fy)
{
st[make_pair(sx[k],sx[t])]+=1;
st[make_pair(sx[t],sx[k])]+=1;
}
}
}
}
}
i=j;
}
for(i=1;i<=q;i++)
ans[i].x+=st[make_pair(ans[i].u,ans[i].v)];
for(i=1;i<=q;i++)
printf("%d\n",ans[i].x);
return 0;
}