bzoj 1050 & bzoj 3669 spfa动态加点

两个状态量,有点像控制变量法,单调枚举一个量,spfa维护另一量。

/*************************
    bzoj 1050
    Status: Accepted
    spfa动态加点 (正解是枚举最小点+并查集,表示还是不会写并查集) 
    2015-0925
*************************/ 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=500+10;
const int maxm=5000*2+10;
const int INF=10000000;
struct Edge{
    int to,next,speed;
};
Edge e[maxm];
int head[maxn],etot=0;
struct AEdge{
    int u,v,speed;
    bool operator < (const AEdge &x)const{
        return speed>x.speed;
    }
};
AEdge aE[maxm];
void addEdge(int u,int v,int speed,int ex){
    if(ex==1){
        aE[etot/2].u=u; aE[etot/2].v=v; aE[etot/2].speed=speed;
    }
    e[etot].speed=speed;
    e[etot].to=v;
    e[etot].next=head[u];
    head[u]=etot++;
}
//
int n,m,s,t;

void read_in(){
    memset(head,-1,sizeof(head));
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x,y,speed;
        cin>>x>>y>>speed;
        addEdge(x,y,speed,1);
        addEdge(y,x,speed,0);
    }
    cin>>s>>t;
    sort(aE,aE+etot/2);
}
queue<int>q;
bool in_queue[maxn];
int d[maxn];
void spfa(int current_speed){
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].to,speed=e[i].speed;
            if(speed<current_speed)continue;
            int tmp=max(d[u],speed);
            if(tmp<d[v]){
                d[v]=tmp;
                if(!in_queue[v]){
                    in_queue[v]=true;
                    q.push(v);
                }
            }
        }
        in_queue[u]=false;
    }
}
int gcd(int x,int y){
    if(y==0)return x;
    return gcd(y,x%y);
}
void solve(){
    double ans=INF;
    int ans1,ans2;
    memset(in_queue,0,sizeof(in_queue));
    for(int i=1;i<=n;i++)d[i]=INF;
    d[s]=0;
    //    
    int i=0,current_speed=0;
    while(i<etot/2){
        current_speed=aE[i].speed;
        while(aE[i].speed==current_speed){
            int u=aE[i].u,v=aE[i].v;
            if(d[u]<INF&&!in_queue[u]){in_queue[u]=true; q.push(u);}
            if(d[v]<INF&&!in_queue[v]){in_queue[v]=true; q.push(v);}
            i++; 
        }
        spfa(current_speed);
        if(d[t]<INF&&double(d[t])/double(current_speed)<ans){
            ans=double(d[t])/double(current_speed);
            ans1=d[t]; ans2=current_speed;
        }
    }
//
    if(ans>=INF)cout<<"IMPOSSIBLE"<<endl;
    else {
        if(ans1%ans2==0)cout<<ans1/ans2<<endl;
        else {
            int c=gcd(ans1,ans2);
            cout<<ans1/c<<'/'<<ans2/c<<endl;
        }
    }
}
int main(){
    read_in();
    solve();    
    return 0;
}
/*********************
    bzoj 3669
    Status: Accepted
    spfa动态加点 (正解是LCT,表示现在不会) 
    2015-09-25 
*********************/ 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=50000+100;
const int maxm=100000*2+100;
const int INF=1000000;
struct Edge{
    int to,next,wa,wb;
};
Edge e[maxm];
int head[maxn],etot=0;
struct AEdge{
    int u,v,wa,wb,idx;
    AEdge(int u,int v,int wa,int wb,int idx):u(u),v(v),wa(wa),wb(wb),idx(idx){}
    AEdge(){}
    bool operator < (const AEdge &x)const{
        return wa<x.wa;
    }
};
AEdge aE[maxm];
void addEdge(int u,int v,int wa,int wb,int ex){
    if(ex==1){
        AEdge tmp(u,v,wa,wb,etot);
        aE[etot/2]=tmp;
    }
    e[etot].wa=wa;
    e[etot].wb=wb;
    e[etot].to=v;
    e[etot].next=head[u];
    head[u]=etot++;
}
//
int n,m;
void read_in(){
    memset(head,-1,sizeof(head));
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x,y,a,b;
        scanf("%d%d%d%d",&x,&y,&a,&b);
        addEdge(x,y,a,b,1);
        addEdge(y,x,a,b,0);
    }
    sort(aE,aE+etot/2);
}
//
int d[maxn];
int in_queue[maxn];
//
queue<int>q;
void spfa(int current_wa){
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].to,wa=e[i].wa,wb=e[i].wb;
            if(wa>current_wa)continue;
            int tmp=max(d[u],wb);
            //
            //cout<<"Can this v change? "<<u<<' '<<v<<endl; 
            if(tmp<d[v]){
                //
                //cout<<"Yes it can"<<endl;
                d[v]=tmp;
                if(!in_queue[v]){
                    //
                    //cout<<"Even not in queue"<<endl;
                    q.push(v);
                    in_queue[v]=true;
                }
            }
        }
        in_queue[u]=false;
    }
}
//
void solve(){
    memset(in_queue,0,sizeof(in_queue));
    for(int i=1;i<=n;i++){
        d[i]=INF;
    }
    d[1]=0;
//
    int ans=INF;
    int i=0,current_wa=0;
    while(i<etot/2){
        current_wa=aE[i].wa;
        while(aE[i].wa==current_wa){
            int u=aE[i].u,v=aE[i].v;
            if(d[u]<INF&&!in_queue[u]){in_queue[u]=true; q.push(u);}
            if(d[v]<INF&&!in_queue[v]){in_queue[v]=true; q.push(v);}
            i++;
        }
        spfa(current_wa);
        ans=min(ans,current_wa+d[n]);
    }
    if(d[n]>=INF)cout<<-1<<endl;
    else cout<<ans<<endl;
}
int main(){
    read_in();
    solve();
    return 0;
}

 

posted @ 2015-09-25 17:31  JimmyLin^_^  阅读(214)  评论(0编辑  收藏  举报