id=99
自己在比赛时候写的代码不是spfa,其实写的就只是迷宫找最短路那种东东,所以我要判断要不要把走过的点再走过一次,,,然后就以为有思维含量了,,
其实这道题也就只是一个简单的spfa,只是距离状态多加了一维而已,
spfa:不需要用vis 数组,因为如果没有更新就不会放入节点,,
迷宫的最短路:要vis,。。。。
迷宫写法代码:
using namespace std;
const int maxn=10005;
int n,m;
int e,tol;
struct Edge{
int a,b,v,nxt;
int visj;
int viso;
}edge[maxn*4];
int head[maxn];
struct Node{
int s,id;
bool friend operator<(Node a,Node b){
return a.s>b.s;
}
}node[maxn];
void addedge(int u,int v,int a,int b){
edge[tol].v=v;edge[tol].nxt=head[u];
edge[tol].a=a;edge[tol].b=b;
head[u]=tol++;
}
void spfa(int st){
priority_queue<Node>que;
Node s;
s.id=st;
s.s=0;
que.push(s);
while(!que.empty()){
Node now=que.top();que.pop();
if(now.id==e){
cout<<now.s<<'\n';return;
}
//cout<<"time"<<now.s<<endl;
if(now.s%2==1){
for(int i=head[now.id];i!=-1;i=edge[i].nxt){
int v=edge[i].v;
if(edge[i].visj)continue;
edge[i].visj=1;
Node tmp=now;
tmp.s+=edge[i].b;
tmp.id=v;
//cout<<now.id<<' '<<now.s<<' '<<v<<endl;
que.push(tmp);
}
}
else{
for(int i=head[now.id];i!=-1;i=edge[i].nxt){
int v=edge[i].v;
if(edge[i].viso)continue;
edge[i].viso=1;
Node tmp=now;
tmp.s+=edge[i].a;
tmp.id=v;
//cout<<now.id<<' '<<now.s<<' '<<v<<endl;
//cout<<"bug1 "<<v<<endl;
que.push(tmp);
}
}
}
}
void init(){
memset(head,-1,sizeof(head));
memset(edge,0,sizeof(edge));
memset(node,0,sizeof(node));
tol=0;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
init();
int s;
scanf("%d%d%d%d",&n,&m,&s,&e);
for(int i=1;i<=m;++i){
int u,v,a,b;
scanf("%d%d%d%d",&u,&v,&a,&b);
addedge(u,v,a,b);
addedge(v,u,a,b);
}
spfa(s);
}
}spfa 利用了奇偶性这一天然的划分, 所以对于一个点的最小时间,只有奇数时间到或者偶数时间到。,
using namespace std;
const int maxn=10005;
int d[maxn][2];
int n,m,s,e,tol;
int head[maxn];
struct Node{
int id;
int s;
};
struct Edge{
int v,nxt,a,b;
}edge[maxn*4];
void addedge(int u,int v,int a,int b){
edge[tol].v=v;edge[tol].nxt=head[u];
edge[tol].a=a;edge[tol].b=b;
head[u]=tol++;
}
void spfa(int st){
queue<Node>que;
Node a;
d[st][0]=0;
a.s=0;a.id=st;
que.push(a);
while(!que.empty()){
Node now=que.front();que.pop();
int u=now.id;
int s=now.s;
if(s%2==1){
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].v;
int tols=s+edge[i].b;
if(tols%2){
if(d[v][1]>tols){
d[v][1]=tols;
Node tmp;tmp.s=tols;tmp.id=v;
que.push(tmp);
}
}
else{
if(d[v][0]>tols){
d[v][0]=tols;
Node tmp;tmp.s=tols;tmp.id=v;
que.push(tmp);
}
}
}
}
else{
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].v;
int tols=s+edge[i].a;
if(tols%2){
if(d[v][1]>tols){
d[v][1]=tols;
Node tmp;tmp.s=tols;tmp.id=v;
que.push(tmp);
}
}
else{
if(d[v][0]>tols){
d[v][0]=tols;
Node tmp;tmp.s=tols;tmp.id=v;
que.push(tmp);
}
}
}
}
}
}
void init(){
memset(d,inf,sizeof(d));
memset(head,-1,sizeof(head));
memset(edge,0,sizeof(edge));
tol=0;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
init();
scanf("%d%d%d%d",&n,&m,&s,&e);
for(int i=1;i<=m;++i){
int u,v,a,b;
scanf("%d%d%d%d",&u,&v,&a,&b);
addedge(u,v,a,b);
addedge(v,u,a,b);
}
spfa(s);
cout<<min(d[e][1],d[e][0])<<'\n';
}
}别人的这个代码一定很经典,自己暂时看不懂。。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<vector>
#include<string>
#include<cmath>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int mod = 1000000007;
const int maxm = 440005;
const int maxn = 30005;
int n, m;
struct edge{
int to,nex,val;
}e[maxm];
int head[maxn];
int tot;
int s,t;
bool vis[maxn];
ll dis[maxn];
void adde(int u,int v,int a){
e[tot].to=v;
e[tot].nex=head[u];
e[tot].val=a;
head[u]=tot++;
}
struct Node{
int id,dis;
bool operator < ( const Node &b)const{
return dis > b.dis;
}
};
void dij(int s){
priority_queue<Node> que;
memset(vis,0,sizeof(vis));
memset(dis,0x3f,sizeof(dis));
dis[s] = 0;
que.push({s,0});
while(!que.empty()){
int u = que.top().id;
que.pop();
vis[u] = 1;
for(int i = head[u];i!=-1;i = e[i].nex){
int v = e[i].to;
if(!vis[v] && dis[v] > dis[u] + e[i].val){
dis[v] = dis[u] + e[i].val;
que.push({v,dis[v]});
}
}
}
}
int main() {
int ta,x,y,a,b;
scanf("%d",&ta);
while(ta--){
scanf("%d%d%d%d",&n,&m,&s,&t);
memset(head,-1,sizeof(head));
tot=0;
for(int i=0;i<m;i++){
scanf("%d%d%d%d",&x,&y,&a,&b);
if(a&1){
adde(x,y+n,a);
adde(y,x+n,a);
}
else{
adde(x,y,a);
adde(y,x,a);
}
if(b&1){
adde(x+n,y,b);
adde(y+n,x,b);
}
else{
adde(x+n,y+n,b);
adde(y+n,x+n,b);
}
}
dij(s);
printf("%d\n",min(dis[t],dis[t+n]));
}
return 0;
}
395

被折叠的 条评论
为什么被折叠?



