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;
}
View Code

方法二:反向建图

使用封装+引用 ,  因为这里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;
}
View Code

 

我的未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;
}
View Code

 

posted @ 2018-09-06 11:57  WindFreedom  阅读(398)  评论(0编辑  收藏  举报