思路请看题解,讲的非常详细,细节请看我
一道很多细节的题
1.初始化要赋1e9
2.只有在两个村庄都重建完之后,一条路才通
3.一条路都通了之后,两个村庄都要再走一遍
4.村庄编号从0开始,而不是从1开始
5.弹出重建完成的村庄时,迭代器it记得加上判断不超过n,因为t为零时永远小于when会陷入死循环,也可以设t[n]正无穷,代表村庄n重建时间无穷大(即永远不可能建成)
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct tong
{
ll pos;
ll val;
};
vector<tong> G[205];
int main()
{
ll n,m;
scanf("%lld%lld",&n,&m);
ll t[205]={0};
for(ll i=0;i<n;i++)scanf("%d",&t[i]);
ll dis[205][205]={0};
for(ll i=0;i<n;i++)
for(ll j=i;j<n;j++)dis[i][j]=dis[j][i]=1e9;
for(ll i=1;i<=m;i++)
{
ll x,y,d;
scanf("%lld%lld%ld",&x,&y,&d);
if(x<y)swap(x,y);
G[x].push_back(tong{y,d});
}
ll q;
scanf("%lld",&q);
ll it=1;
while(q--)
{
ll x,y,when;
scanf("%lld%lld%lld",&x,&y,&when);
while(t[it]<=when&&it<n)
{
for(ll k=0;k<G[it].size();k++)
{
ll too=G[it][k].pos;
dis[it][too]=dis[too][it]=min(G[it][k].val,dis[too][it]);
for(ll i=0;i<n;i++)
for(ll j=i+1;j<n;j++) dis[i][j]=dis[j][i]=min(dis[i][too]+dis[too][j],dis[j][i]);
}
for(ll i=0;i<n;i++)
for(ll j=i+1;j<n;j++) dis[i][j]=dis[j][i]=min(dis[i][it]+dis[it][j],dis[j][i]);
it++;
}
if(dis[x][y]>=1e9)puts("-1");
else printf("%lld\n",dis[x][y]);
}
return 0;
}
标签:205,P1119,ll,村庄,灾后,1e9,重建
From: https://www.cnblogs.com/pure4knowledge/p/17884060.html