您的位置:首页 > 其它

SCU 4444 Travel (完全图 最短路 set )

2017-07-30 13:53 330 查看

思路:

首先考虑a小于等于b,那么我们只需要跑一边由a边建的图就好了,因为原图是完全图,所以得到的结果和b取最小值就好。

然后考虑a大于b,进行一遍bfs,注意每个点最多计算一次,所以我们可以用两个set集合来标记这个点还能不能用(能用的话用set.count(v)=1来表示),如果此时某个能用的点这次因为有a边而不能用了,那么把这个点放进另一个set:ts,这个集合是下次可以接着用的点。

总之卡点是bfs,dijsktra直接板子。

话说这个bfs写的是真好(不是夸自己,从dalao那偷来的想法2333

(话说读书人的事怎么能叫偷2333

#include <iostream>
#include <cstdio>
#include <queue>
#include <set>
#include <string.h>
#include <algorithm>
#define inf 0x3f3f3f3f
typedef long long int lli;
using namespace std;
const int mod = 1e9+7;

const int maxn = 102000;
struct edge{
int to,v,next;
edge(){}
edge(int tt,int vv){to=tt,v=vv;}
bool operator < (const edge&b) const {
return v>b.v;
}
}ed[1200000];
int head[maxn],cnte;
bool vis[maxn];
lli dis[maxn];

void ae(int x,int y,int v){
ed[++cnte].to = y;
ed[cnte].v = v;
ed[cnte].next = head[x];
head[x] = cnte;
}

void dij(int s){
priority_queue<edge> q;
int now = head[s];
memset(dis,0x3f,sizeof(dis));
while(now != -1){
dis[ed[now].to] = ed[now].v;
q.push(ed[now]);
now = ed[now].next;
}
vis[s] = true;
dis[s] = 0;
int pos;
while(!q.empty()){
pos = q.top().to;
now = head[pos];
while(vis[pos] == false && now != -1){
int v = ed[now].to;
if(dis[v] > dis[pos]+ed[now].v){
dis[v] = dis[pos]+ed[now].v;
q.push(edge(ed[now].to,dis[v]));
}
now = ed[now].next;
}
vis[pos] = true;
q.pop();
}
}

int n,m,a,v1,v2;lli b;

set<int>st,ts;
set<int>::iterator it;
lli bfs(int a,int b){
dis
=inf;
queue<int> q;int u;
st.clear(); ts.clear();
for(int i=2;i<=n;i++){
st.insert(i);
}
dis[1] = 0;q.push(1);
while(!q.empty()){
u = q.front();q.pop();
for(int i = head[u];~i;i=ed[i].next){
int v = ed[i].to;
if(st.count(v)==1){
st.erase(v);ts.insert(v);
}
}
for(it=st.begin();it!=st.end();it++){
dis[*it] = dis[u] + 1;
q.push(*it);
}
st=ts;
ts.clear();
}
return dis
*b<a ? dis
*b:a;
}

int main(){
while(~scanf("%d%d%d%lld",&n,&m,&a,&b)){
memset(head,-1,sizeof(head));cnte = 0;
memset(vis,false,sizeof(vis));
int flag = 0;
for(int i = 1;i <= m;i++){
scanf("%d%d",&v1,&v2);
ae(v1,v2,a);ae(v2,v1,a);
}
lli ans;
if(a <= b){
dij(1);
ans = min(dis
,b);
}
else{
ans = bfs(a,b);
}
printf("%lld\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: