您的位置:首页 > 其它

Codeforces Round #436 (Div. 2)

2017-09-28 21:00 447 查看
这套题…

前两题出的太慢了,A题题目看的太慢,然后单纯模拟,wa了两发,然后重写了一下过了。

BC没有什么问题。

D题,emmm,是先减再换,不小心先换再减了,又贡献了几发==

E题,有限制条件的01背包,在这片博客的最后有分析

F题。参考了代码

开始感觉就是个离线操作,将所有询问都存下来,将相同起点的一起询问(询问就是dfs),然后时间复杂度为n*m。

dfs开始想的比较单纯,从起点开始走字典序最小的那条路,在遍历的点中,如果是要查询的终点的话,就把答案记下来。如果遇到环的话全部跳出,没有遍历到的询问就都为-1.

然后WA了,因为首先,如果有环的话,不一定要直接跳出,有些点还要遍历,比如这个图

1 2

2 3

3 4

4 5

2 5

如果查1 5 2的话,结果就是-1。但是1到5并不经过那个环。所以说,这个就是要判断1个点到另一个的路径上有没有环

如果有环的话,回到这个环的起点,继续dfs,那么可以用tarjan

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const int inf =1e6;
const int maxn = 3010;

int st[maxn],dfn[maxn],res[400010],low[maxn],vis_st[maxn];
struct node
{
int id,from,to,k;
node(){}
node(int a,int d,int b,int c){
id=a,from=d,to=b,k=c;
}
};
node qs[400010];

vector<int> v[maxn];
vector<node> Q[maxn];
bool cmp(node a1,node a2)
{
if(a1.from!=a2.from)
return a1.from<a2.from;
else return a1.to<a2.to;
}
int top=0,tot=0;

void Tarjan(int u,int ok)
{
st[++top]=u;
dfn[u]=++tot;
low[u]=inf;//这个开始设为比较大的数,之后如果low比dfn小的话,证明之间有环
vis_st[u]=1;
if(ok)
for(int i=0;i<Q[u].size();i++)
if(Q[u][i].k<=top) res[Q[u][i].id]=st[Q[u][i].k];
for(int i=0;i<v[u].size();i++)
{
int t=v[u][i];
if(!dfn[t])
{
Tarjan(t,ok&&dfn[u]<low[u]);
low[u]=min(low[u],low[t]);
}
else if(vis_st[t]) low[u]=min(low[u],dfn[t]);
}
vis_st[u]=0;
top--;
}
int main()
{
int n,m,q;
scanf("%d %d %d",&n,&m,&q);
memset(res,-1,sizeof(res));
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d %d",&a,&b);
v[a].push_back(b);
}
for(int i=1;i<=n;i++)
sort(v[i].begin(),v[i].end());
for(int i=1;i<=q;i++)
{
int a,b,k;
scanf("%d %d %d",&a,&b,&k);
qs[i]=node(i,a,b,k);
}
sort(qs+1,qs+q+1,cmp);
for(int i=1;i<=q;i++)
{
Q[qs[i].to].push_back(qs[i]);
if(qs[i].from!=qs[i+1].from)
{
mem(st,0);mem(dfn,0);mem(vis_st,0);mem(low,0);
tot=0,top=0;
Tarjan(qs[i].from,1);
for(int j=1;j<=n;j++)
Q[j].clear();
}
}
for(int i=1;i<=q;i++)
printf("%d\n",res[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: