您的位置:首页 > 其它

codevs 1817 灾后重建

2016-10-10 21:56 148 查看
/*
暴力暴力
离线每次添边
堆优化dij 70
SPFA 80.....
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#define maxn 210
using namespace std;
int n,m,Q,num,head[maxn],dis[maxn],t[maxn],f[maxn];
queue<int>q;
struct edge{
int v,pre,t;
}e[maxn*maxn];
struct node{
int u,v,r,t,ans;
}p[maxn*maxn*2],P[maxn*maxn*2];
int cmp1(const node &x,const node &y){
return x.t<y.t;
}
int cmp2(const node &x,const node &y){
return x.r<y.r;
}
void Add(int from,int to,int dis){
num++;e[num].v=to;
e[num].pre=head[from];
e[num].t=dis;
head[from]=num;
}
int SPFA(int u,int v,int now){
if(now<t[u]||now<t[v])return -1;
memset(dis,127/3,sizeof(dis));
memset(f,0,sizeof(f));
int inf=dis[0];f[u]=1;
dis[u]=0;q.push(u);
while(!q.empty()){
int k=q.front();q.pop();f[k]=0;
for(int i=head[k];i;i=e[i].pre){
int v=e[i].v;
if(dis[v]>dis[k]+e[i].t){
dis[v]=dis[k]+e[i].t;
if(f[v]==0){
f[v]=1;q.push(v);
}
}
}
}
if(dis[v]==inf)return -1;
return dis[v];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&t[i]);
int u,v,ti;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&ti);
p[i].u=u;p[i].v=v;p[i].r=ti;
p[i].t=max(t[u],t[v]);
}
sort(p+1,p+1+m,cmp1);
scanf("%d",&Q);
for(int i=1;i<=Q;i++){
scanf("%d%d%d",&u,&v,&ti);
P[i].t=ti;P[i].u=u;
P[i].v=v;P[i].r=i;
}
sort(P+1,P+1+Q,cmp1);
int now=0,x=1;
for(int i=1;i<=Q;i++){
now=P[i].t;
while(p[x].t<=now&&x<=m){
Add(p[x].u,p[x].v,p[x].r);
Add(p[x].v,p[x].u,p[x].r);
x++;
}
P[i].ans=SPFA(P[i].u,P[i].v,now);
}
sort(P+1,P+1+Q,cmp2);
for(int i=1;i<=Q;i++)
printf("%d\n",P[i].ans);
return 0;
}


/*
加深了对floyed的理解
实质是dp
d[k][i][j] 表示i-j只经过1-k的节点作为中间点的最短路
有两种情况 走或者不走k
f[k][i][j]=min(f[k-1][i][j],f[k-1][i][k]+f[k-1][k][j])
可以压缩空间压掉第一维
嗯这个题各种提示用floyed啊
首先t是小到大的
还有就是输入数据时不降的
我还傻傻的离线sort做....
结合题目每次询问i->j 保证中间经过的一定是修好了的城市
只要满足 经过的在这之前都修好了
那根据对floyed的理解 保证循环k<=t就好了
*/
#include<cstdio>
#define maxn 210
using namespace std;
int n,m,k,Q,t[maxn],f[maxn][maxn],inf;
int min(int x,int y){
return x<y?x:y;
}
int init(){
int x=0;char s=getchar();
while(s<'0'||s>'9')s=getchar();
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x;
}
int Floyed(int u,int v,int ti){
if(t[u]>ti||t[v]>ti)return -1;
for(;k<n&&t[k]<=ti;k++)
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
if(f[u][v]==inf)return -1;
else return f[u][v];
}
int main()
{
n=init();m=init();
for(int i=0;i<n;i++)
t[i]=init();
int u,v,ti;
inf=0x3f3f3f3f;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
f[i][j]=inf;
for(int i=0;i<n;i++)
f[i][i]=0;
for(int i=1;i<=m;i++){
u=init();v=init();ti=init();
f[u][v]=f[v][u]=ti;
}
Q=init();
while(Q--){
u=init();v=init();ti=init();
printf("%d\n",Floyed(u,v,ti));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: