Analyse:题目给一些区间,要求是找some区间,使得所选区间并集包含题目【s,e】,且权值和最小。
*加上 (i)->(i-1) 权值为0的边。
*每边为s->e+1,,刚好是区间连起来
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string>
#include<queue>
#include<deque>
#include<stack>
#include<map>
#include<set>
#define INF 0x7fffffff
#define SUP 0x80000000
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
const int N=100007;
struct Edge{
int to,w;
int next;
}p[200007]; //这个貌似要开大......
int tot;
int adj[N],dis[N],vis[N],cnt[N];
void addedge(int u,int v,int w)
{
p[tot].to=v;
p[tot].w=w;
p[tot].next=adj[u];
adj[u]=tot++;
}
bool spfa(int s,int n)
{
fill(vis,vis+N,0);
fill(cnt,cnt+N,0);//cout<<"-"<<endl;
queue<int> que;
que.push(s);
dis[s]=0;
vis[s]=cnt[s]=1;
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=0;
for(int i=adj[u];i!=-1;i=p[i].next)
{
int v=p[i].to;
if(dis[v]>dis[u]+p[i].w)
{
dis[v]=dis[u]+p[i].w;
if(!vis[v])
{
vis[v]=1;
que.push(v);
cnt[v]++;
if(cnt[v]>n) return false;
}
}
}
}
return true;
}
int main()
{
int n,s,e;
while(scanf("%d%d%d",&n,&s,&e)==3)
{
tot=0;
mem(adj,-1);
int st,en,w;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&st,&en,&w);
if(st<=e&&en>=s)
addedge(max(st,s),min(en+1,e+1),w);
}
for(int i=e+1;i>=s;i--){
addedge(i,i-1,0);
}
fill(dis+1,dis+1+e+1,INF);
spfa(s,e+1-s+1);
if(dis[e+1]!=INF) printf("%d\n",dis[e+1]);
else
printf("-1\n");
}
return 0;
}