hdu3499(分层图最短路 or 反向建图)
方法一:分层图
#include<bits/stdc++.h> #define per(i,a,b) for(int i=a;i<=b;i++) #define mod 1000000007 using namespace std; typedef long long ll; const ll inf =23333333333333333LL; const double eps=1e-8; int T; int read(){ char ch=getchar(); int res=0,f=0; while(ch<'0' || ch>'9'){f=(ch=='-'?-1:1);ch=getchar();} while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();} return res*f; } // ------------------------head const int siz=100005; map<string,int> mp; int mcnt=0,n,m; int d; char x[15],y[15],schar[15],echar[15]; int head[siz],Enum=0; ll dis[siz][2]; bool vis[siz][2]; int st,ed; struct Edge{int to,w,ne;}edge[siz*5]; void add_edge(int a,int b,int c){ edge[Enum].to=b; edge[Enum].w=c; edge[Enum].ne=head[a]; head[a]=Enum++; } void init() { memset(head,-1,sizeof(head)); Enum=0; mp.clear(); mcnt=0; } int _hash(char *s){//char*作为实参传给string形参会自动变 if(mp.count(s)>0)return mp[s];//string作为形参传给char*要转变s.c_str(); else return mp[s]=mcnt++; } struct Qnode{ int u; ll _dis; int layer;//位于分层图的哪层 Qnode(){} Qnode(ll a,int b,int c):_dis(a),u(b),layer(c){} bool operator<(const Qnode&rhs)const{return _dis>rhs._dis;}//一定要加const }; void Dijkstra(){ priority_queue<Qnode>que; while(!que.empty())que.pop(); memset(vis,false,sizeof(vis)); per(i,0,n){dis[i][0]=inf;dis[i][1]=inf;} que.push(Qnode(0LL,st,0)); dis[st][0]=0; //注意初始化的是st点,而不是0点,这里没注意到!!! vis[st][0]=true; Qnode tmp; while(!que.empty()){ tmp=que.top();que.pop(); int u=tmp.u,layer=tmp.layer; ll _dis=tmp._dis; //printf("dis:%lld u:%d layer:%d\n",_dis,u,layer);// vis[u][layer]=true; //if(u==ed && layer==1)return;// //printf("dis[%d]:%lld\n",u,dis[u][0]);// for(int i=head[u];i!=-1;i=edge[i].ne){ int v=edge[i].to,w=edge[i].w; //printf("w:%d\n",w);exit(0);// //printf("v:%d \n");// //printf("dis[u][layer]:%lld\n",dis[u][layer]);// //printf("dis[v][layer+1]:%lld dis[v][layer]:%lld w:%d\n",dis[v][layer+1],dis[v][layer],w);// //if(dis[v][layer+1]>dis[u][layer]+w/2)printf("cas1 ok\n");else printf("cas1 no\n");// if(layer<1 && !vis[v][layer+1] &&dis[v][layer+1]>dis[u][layer]+w/2){ dis[v][layer+1]=dis[u][layer]+w/2; //printf("Push v%d dis:%lld layer:%d\n",v,dis[v][layer],layer+1);// que.push(Qnode(dis[v][layer+1],v,layer+1)); } if(!vis[v][layer] && dis[v][layer]>dis[u][layer]+w){ dis[v][layer]=dis[u][layer]+w; que.push(Qnode(dis[v][layer],v,layer)); } } } } int main() { while(scanf("%d %d",&n,&m)!=EOF){ init(); per(i,1,m){ scanf("%s %s %d",x,y,&d); int xn=_hash(x),yn=_hash(y); //printf("%s:%d %s:%d d:%d\n",x,xn,y,yn,d);// add_edge(xn,yn,d); } scanf("%s %s",schar,echar); if(mp.count(schar)==0||mp.count(echar)==0){printf("-1\n");continue;} st=_hash(schar);ed=_hash(echar); //printf("%s:%d %s:%d\n",schar,st,echar,ed);// Dijkstra(); ll ans=min(dis[ed][0],dis[ed][1]); if(ans==inf)printf("-1\n"); else printf("%lld\n",ans); } return 0; }
方法二:反向建图
使用封装+引用 , 因为这里dijkstra()两次,不封装就要每种变量开两次,代码看上去就会有点乱QwQ
#include<bits/stdc++.h> #define per(i,a,b) for(int i=a;i<=b;i++) #define mod 1000000007 using namespace std; typedef long long ll; const ll inf =23333333333333333LL; const double eps=1e-8; int T; int read(){ char ch=getchar(); int res=0,f=0; while(ch<'0' || ch>'9'){f=(ch=='-'?-1:1);ch=getchar();} while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();} return res*f; } // ------------------------head #define siz 100010 int n,m; struct Edge{ int from,to,ne; ll dis; Edge(){} Edge(int a,int b,int c,int d):dis(a),from(b),to(c),ne(d){} }; struct HeapNode{ ll dis; int u; HeapNode(){} HeapNode(ll a,int b):dis(a),u(b){} bool operator<(const HeapNode&rhs)const{ return dis>rhs.dis; } }; struct Dijkstra{ int n,Enum; int head[siz]; Edge edge[siz*5]; ll dis[siz]; bool vis[siz]; void init(){ Enum=0; memset(head,-1,sizeof(head)); } void add_edge(int from,int to,int d){ edge[Enum]=Edge(d,from,to,head[from]); head[from]=Enum++; } void dijkstra(int st){ priority_queue<HeapNode>que; while(!que.empty())que.pop(); memset(vis,false,sizeof(vis)); per(i,0,n-1)dis[i]=(i==st?0:inf); //printf("dis:");// //per(i,0,n-1)printf("%lld ",dis[i]);printf("\n");exit(0);// vis[st]=true; que.push(HeapNode(0LL,st)); while(!que.empty()){ HeapNode tmp=que.top();que.pop(); int u=tmp.u; //printf("u:%d dis:%lld\n",u,tmp.dis);// //if(vis[u]==true)continue; for(int i=head[u];i!=-1;i=edge[i].ne){ int v=edge[i].to,w=edge[i].dis; //printf("v:%d w:%d dis[u]:%lld dis[v]:%lld\n",v,w,dis[u],dis[v]);// if(dis[v]>dis[u]+w){ dis[v]=dis[u]+w; //printf("Push v:%d dis[v]:%lld\n",v,dis[v]);// que.push(HeapNode(dis[v],v)); } } } } }DJ1,DJ2; map<string,int>mp; int mp_cnt=0; int ID(char*s){ if(mp.count(s)>0)return mp[s]; else return mp[s]=mp_cnt++; } int main() { //freopen("Data_In.txt","r",stdin); char x[15],y[15],schar[15],echar[15]; int xn,yn; int d,st,ed; while(scanf("%d %d",&n,&m)!=EOF){ mp.clear(); mp_cnt=0; DJ1.init();DJ2.init(); DJ1.n=DJ2.n=n; per(i,0,m-1){ scanf("%s %s %d",x,y,&d); xn=ID(x);yn=ID(y); DJ1.add_edge(xn,yn,d); DJ2.add_edge(yn,xn,d); } scanf("%s %s",schar,echar); if(mp.count(schar)==0||mp.count(echar)==0){ printf("-1\n");continue; } st=ID(schar);ed=ID(echar); DJ1.dijkstra(st);DJ2.dijkstra(ed); //per(i,0,n-1)printf("%lld ",DJ1.dis[i]);printf("\n");return 0;// if(DJ1.dis[ed]==inf){ printf("-1\n");continue; } ll ans=inf; for(int i=0;i<DJ1.Enum;i++){ int u=DJ1.edge[i].from,v=DJ1.edge[i].to; int d=DJ1.edge[i].dis; ans=min(ans,DJ1.dis[u]+DJ2.dis[v]+d/2); } printf("%lld\n",ans); } return 0; }
我的未ac版
#include<bits/stdc++.h> #define per(i,a,b) for(int i=a;i<=b;i++) #define mod 1000000007 using namespace std; typedef long long ll; const ll inf =23333333333333333LL; const double eps=1e-8; int T; int read(){ char ch=getchar(); int res=0,f=0; while(ch<'0' || ch>'9'){f=(ch=='-'?-1:1);ch=getchar();} while(ch>='0'&&ch<='9'){res=res*10+(ch-'0');ch=getchar();} return res*f; } // ------------------------head #define siz 100005 int n,m; int head1[siz],head2[siz],Enum1,Enum2; ll dis1[siz],dis2[siz]; bool vis1[siz],vis2[siz]; struct Edge{ int from,to,ne; int dis; }edge1[siz*5],edge2[siz*5]; map<string,int>mp; int mp_cnt=0; void init(){ memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); Enum1=Enum2=0; mp_cnt=0; mp.clear(); } void add_edge(int a,int b,int c,int head[],Edge edge[],int &E){ edge[E].from=a; edge[E].to=b; edge[E].dis=c; edge[E].ne=head[a]; head[a]=E++; } int _hash(char s[]){ if(mp.count(s)>0)return mp[s]; else return mp[s]=mp_cnt++; } struct Qnode{ int u; ll _dis; Qnode(){} Qnode(ll a,int b):_dis(a),u(b){} bool operator<(const Qnode&rhs)const{return _dis>rhs._dis;} }; void Dijkstra(int st,int head[],Edge edge[],ll dis[],bool vis[]){ memset(vis,false,sizeof(vis)); priority_queue<Qnode>que; while(!que.empty())que.pop(); per(i,0,n-1)dis[i]=inf; dis[st]=0; vis[st]=true; que.push(Qnode(0LL,st)); Qnode tmp; while(!que.empty()){ tmp=que.top();que.pop(); int u=tmp.u; ll _dis=tmp._dis; //printf("u:%d dis:%lld\n",u,_dis);// vis[u]=true; for(int i=head[u];i!=-1;i=edge[i].ne){ int v=edge[i].to,w=edge[i].dis; if(vis[v]==false && dis[v]>_dis+w){ dis[v]=_dis+w; que.push(Qnode(dis[v],v)); } } } } int main() { freopen("Data_In.txt","r",stdin); char x[15],y[15],schar[15],echar[15]; int d,st,ed; while(scanf("%d %d",&n,&m)!=EOF){ init(); per(i,1,m){ scanf("%s %s %d",x,y,&d); int xn=_hash(x),yn=_hash(y); //printf("%s:%d %s:%d d:%d\n",x,xn,y,yn,d);// add_edge(xn,yn,d,head1,edge1,Enum1); add_edge(yn,xn,d,head2,edge2,Enum2); } scanf("%s %s",schar,echar); if(mp.count(schar)==0||mp.count(echar)==0){printf("-1\n");continue;} st=_hash(schar);ed=_hash(echar); //printf("st:%d ed:%d\n",st,ed);// //printf("%s:%d %s:%d\n",schar,st,echar,ed);// Dijkstra(st,head1,edge1,dis1,vis1); Dijkstra(ed,head2,edge2,dis2,vis2); //per(i,0,n-1)printf("%lld\n",dis1[i]);printf("\n");// ll ans=inf; if(dis1[ed]==inf){printf("-1\n");continue;} for(int i=0;i<Enum1;i++){ int from=edge1[i].from,to=edge1[i].to,_dis=edge1[i].dis; ans=min(ans,dis1[from]+dis2[to]+_dis/2); } //if(ans==inf){printf("-1\n");continue;} printf("%lld\n",ans); } return 0; }