wa70求助!
查看原帖
wa70求助!
210719
Violet___Evergarden楼主2021/8/18 11:58

将每条边用第一个gps认为的时间跑最短路,再用第二个gps认为的跑一遍,最后看每条边会报警几次,跑第三遍。

#include <iostream>
#include <queue>
#include <cstring>
#define int long long
using namespace std;
const int kMaxM=5e5+1;
const int kMaxN=1e5+1;
struct BIAN
{
  int fr,to,p,q;
}b[kMaxM];
struct EDGE1
{
  int to,nt,qu;
}e[4][kMaxM];
int cnt[4],hd[4][kMaxN];
int n,m;
int ans[4][kMaxN];
bool vis[kMaxN];
struct DIAN
{
  int where,dis;
  bool operator <(const DIAN &x)const
  {
    return x.dis<dis;
  }
};
void Add(int num,int a,int b,int c)
{
  e[num][++cnt[num]].to=b;
  e[num][cnt[num]].nt=hd[num][a];
  e[num][cnt[num]].qu=c;
  hd[num][a]=cnt[num];
}
void Dij(int x)
{
  priority_queue<DIAN>q;
  memset(vis,0,sizeof(vis));
  q.push((DIAN){1,0});
  ans[x][1]=0;
  while(!q.empty())
  {
    int now=q.top().where;
    q.pop();
    if(vis[now])continue;
    vis[now]=true;
    for(int i=hd[x][now];i;i=e[x][i].nt)
    {
      if(ans[x][e[x][i].to]>ans[x][now]+e[x][i].qu)
      {
        ans[x][e[x][i].to]=ans[x][now]+e[x][i].qu;
        if(vis[e[x][i].to]==false)
        {
          q.push((DIAN){e[x][i].to,ans[x][e[x][i].to]});
        }
      }
    }
  }
}
signed main()
{
freopen("gpsduel.in","r",stdin);
freopen("gpsduel.out","w",stdout);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
  ans[1][i]=1e17;
  ans[2][i]=1e17;
  ans[3][i]=1e17;
}
for(int i=1;i<=m;i++)
{
  cin>>b[i].fr>>b[i].to>>b[i].p>>b[i].q;
  Add(1,b[i].fr,b[i].to,b[i].p);//第一张图
  Add(2,b[i].fr,b[i].to,b[i].q);//第二张图
}
Dij(1);
Dij(2);//跑两次最短路
int num=0;
for(int i=1;i<=m;i++)
{
  num=0;
  num+=(ans[1][b[i].to]!=ans[1][b[i].fr]+b[i].p)+(ans[2][b[i].to]!=ans[2][b[i].fr]+b[i].q);//计算每条边报警的次数,如果ans[1][b[i].to]!=ans[1][b[i].fr]+b[i].p,代表这条边不是最短路,那么经过这条边就会报警一次
  Add(3,b[i].fr,b[i].to,num);//构第三张图
}
Dij(3);//再来一遍
cout<<ans[3][n];
return 0;
}
2021/8/18 11:58
加载中...