分析
由于数据范围非常小
我们可以有很多大胆的乱搞尝试Dijkstra + DP
我们不知道哪一天会修改路线
那我们就考虑吧所有的情况算出来
也就是Va[i][j]表示第i天到第j天都使用一套方案的最短路
那么我们就可以直接枚举断点
也就是的暴力
DP即可
时间复杂度:
(是因为边数可能会有
)
吐槽
洛谷得了一个最优解,牛客始终拿不到,Rank 1那位巨佬%%%
代码
//P1772
#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <cstdio>
#include <cmath>
#define LL long long
#define Cl(X,Y) memset((X),(Y),sizeof(X))
#define FOR(i,A,B) for(int i=A;i<=B;i++)
#define BOR(i,A,B) for(int i=A;i>=B;i--)
#define Lowbit(X) (X & (-X))
#define Skip cout<<endl;
#define INF 0x3f3f3f3f
#define Mod 998244353
#define Rson (X<<1|1)
#define Lson (X<<1)
using namespace std;
const int MaxN=1e2+10,MaxM=30,MaxP=1e4+10;
int Day,Total,K,Side,u,v,w,Test;
int Next[MaxM*MaxM],End[MaxM*MaxM],Head[MaxM],Cur,Val[MaxM*MaxM];
struct Node { int Opt,From,To; }Line[MaxP];
bool Choose[MaxM],Jud[MaxM];
int Dist[MaxM];
LL DP[MaxN],Va[MaxN][MaxN];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >Mine;
inline void File() {
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
inline int Read() {
int Temp=0;
char Ch=getchar();
while(Ch>'9' || Ch<'0') { Ch=getchar(); }
while(Ch>='0' && Ch<='9') { Temp=(Temp<<1)+(Temp<<3)+(Ch ^ 48); Ch=getchar(); }
return Temp;
}
inline void Add_Edge(int From,int To,int Temp) {
Next[++Cur]=Head[From];
Head[From]=Cur;
End[Cur]=To;
Val[Cur]=Temp;
}
inline void Dijkstra() {
Dist[1]=0;
Mine.push(make_pair(Dist[1],1));
while(!Mine.empty()) {
pair<int,int>New=Mine.top();
Mine.pop();
if(Jud[New.second]) continue;
Jud[New.second]=true;
for(int i=Head[New.second];i;i=Next[i]) {
if(!Choose[End[i]]) continue;
if(New.first+Val[i]<Dist[End[i]]) {
Dist[End[i]]=New.first+Val[i];
Mine.push(make_pair(Dist[End[i]],End[i]));
}
}
}
}
signed main() {
// File();
// ios::sync_with_stdio(false);
Day=Read(); Total=Read(); K=Read(); Side=Read();
FOR(i,1,Side) { u=Read(); v=Read(); w=Read(); Add_Edge(u,v,w); Add_Edge(v,u,w); }
Test=Read();
FOR(i,1,Test) { Line[i].Opt=Read(); Line[i].From=Read(); Line[i].To=Read(); }
FOR(i,1,Day) FOR(j,i,Day) {
Cl(Jud,false); Cl(Dist,0x3f);
while(!Mine.empty()) Mine.pop();
Cl(Choose,true);
FOR(k,1,Test) if(Line[k].From<=j && Line[k].To>=i) { Choose[Line[k].Opt]=false; }
// Skip;
// FOR(i,1,Total) cout<<"i: "<<Choose[i]<<endl;
// Skip;
Dijkstra();
Va[i][j]=Dist[Total];
}
Cl(DP,0x3f);
FOR(i,1,Day) { DP[i]=1ll*Va[1][i]*i; BOR(j,i-1,0) {
DP[i]=min(DP[i],DP[j]+Va[j+1][i]*(i-j)+K);
} }
// FOR(i,1,Day) { FOR(j,i,Day) cout<<"i: "<<i<<" j: "<<j<<" Va: "<<Va[i][j]<<endl; }
// FOR(i,0,Day) cout<<"i: "<<i<<" DP: "<<DP[i]<<endl;
printf("%lld\n",DP[Day]);
// cout<<DP[Day]<<endl;
// fclose(stdin);
// fclose(stdout);
system("pause");
return 0;
} 
京公网安备 11010502036488号