A Timeline
题面
现在有 (n) 个事件,已知事件 (i) 在第 (S_i) 天及以后发生。除此之外,有 (C) 个关系 ((a,~b,~x)),要求事件 (b) 至少在 (a) 发生 (x) 天后发生。
求满足上述事件时各个事件发生的最早时间。
题解
topsort。
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
const int MAXN=200000+5+5;
struct Edge{int u,v,w,next;};
struct data
{
int u,w;
bool operator < (const data &b) const
{
return w==b.w?u<b.u:w>b.w;
}
};
Edge edge[MAXN];
bool vis[MAXN];
int n,m,c,begin[MAXN],super,u,v,w,head[MAXN],dis[MAXN],cnt,in[MAXN];
std::queue<int>que;
void AddEdge(int u,int v,int w)
{
edge[++cnt].u=u;edge[cnt].v=v;edge[cnt].w=w;
edge[cnt].next=head[u];head[u]=cnt;
}
void BFS()
{
que.push(super);
while(!que.empty())
{
int u=que.front();que.pop();
for(int i=head[u];i;i=edge[i].next)
{
dis[edge[i].v]=std::max(dis[edge[i].v],dis[edge[i].u]+edge[i].w);
in[edge[i].v]--;
if(!in[edge[i].v]) que.push(edge[i].v);
}
}
}
int main()
{
freopen("timeline.in","r",stdin);
freopen("timeline.out","w",stdout);
scanf("%d %d %d",&n,&m,&c);
super=n+1;
for(int i=1;i<=n;i++)
{
scanf("%d",&begin[i]);
AddEdge(super,i,begin[i]);
in[i]++;
}
for(int i=1;i<=c;i++)
{
scanf("%d %d %d",&u,&v,&w);
in[v]++;
AddEdge(u,v,w);
}
BFS();
for(int i=1;i<=n;i++)
printf("%d
",dis[i]);
return 0;
}
B Help yourself
题面
给出 (N) 条线段,定义线段的并集和复杂度,求 (2^N) 条线段复杂度之和。
题解
实际上推导了一部分正解。但只写出了前几个点要了个部分分。
Code
#include<cstdio>
#include<map>
const int MAXN=100000+5;
int n,l[MAXN],r[MAXN],belong[MAXN],ans=0,cnt;
void search(int now)
{
std::map<int,int>map;
if(now==n+1)
{
for(int i=1;i<=n;i++)
if(belong[i])map[belong[i]]++;
ans=(ans+map.size())%1000000007;
return;
}
search(now+1);
int temp[30];
temp[0]=cnt;
for(int i=1;i<=n;i++)
temp[i]=belong[i];
for(int i=1;i<=n;i++)
{
if(now==i||!belong[i]) continue;
if((l[now]>=l[i]&&l[now]<=r[i])||(r[now]>=l[i]&&r[now]<=r[i])||(l[now]<=l[i]&&r[now]>=r[i])) map[belong[i]]++;
}
if(!map.size()) belong[now]=++cnt;
if(map.size()==1) belong[now]=map.begin()->first;
if(map.size()>1)
{
belong[now]=++cnt;
for(int i=1;i<=n;i++)
if(map[belong[i]])
{
belong[i]=cnt;
}
}
search(now+1);
for(int i=1;i<=n;i++)
belong[i]=temp[i];
cnt=temp[0];
}
int main()
{
freopen("help.in","r",stdin);
freopen("help.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d %d",&l[i],&r[i]);
search(1);
printf("%d",ans);
return 0;
}