标签:++ clu 第一条 const ios 极限 names for queue
题意:中文题目。。
解题思路:我的做法就是单源最短路中加个记录分数的数组,如果dis[i]到dis[x]的距离可以被优化,那就连记录分数的数组一起优化,如果第二条路和第一条路的距离相等,那就取最大的分数;
代码:#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#define maxn 250001
const int inf=999999;
using namespace std;
struct Edge
{
int next;
int to;
int w;
int g;
}edge[maxn];
struct node
{
int num;
int dist;
node(int _num=0,int _dist=0):num(_num),dist(_dist){}
friend bool operator<(node a,node b)
{
return a.dist>b.dist;
}
};
int head[maxn];
int s[maxn];
int n,m,cnt;
int dis[maxn];
int grade[maxn];
int a[maxn];
bool vis[maxn];
void add(int u,int v,int w,int g)
{
edge[cnt].next=head[u];
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].g=g;
head[u]=cnt++;
}
void dij(int x)
{
priority_queue<node>que;
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(grade,0,sizeof(grade));
dis[x]=0;
que.push(node(x,0));
dis[x]=0;
grade[x]=a[x];
while(!que.empty())
{
node p=que.top();
que.pop();
int now=p.num;
if(vis[now])
continue;
vis[now]=true;
for(int i=head[now];i!=-1;i=edge[i].next)
{
Edge e=edge[i];
if(dis[e.to]>dis[now]+e.w&&!vis[e.to])
{
dis[e.to]=dis[now]+e.w;
grade[e.to]=grade[now]+e.g;
que.push(node(e.to,dis[e.to]));
}
else if(dis[e.to]==dis[now]+e.w&&!vis[e.to])
{
grade[e.to]=max(grade[e.to],grade[now]+e.g);
}
// cout<<e.to<<" "<<grade[e.to]<<endl;
}
}
return;
}
int main()
{
int st,en;
int x,y,w;
memset(head,-1,sizeof(head));
while(cin>>n>>m>>st>>en)
{
memset(head,-1,sizeof(head));
cnt=0;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
{
cin>>x>>y>>w;
add(x,y,w,a[y]);
add(y,x,w,a[x]);
}
dij(st);
cout<<dis[en]<<" "<<grade[en]<<endl;
}
return 0;
}
这里注意:双向边,然后链式前向星存图因为没说边的数量,应该要开的极限点。
标签:++ clu 第一条 const ios 极限 names for queue
原文地址:http://www.cnblogs.com/huangdao/p/7765992.html