hdu 4725 (spfa+建圖) 明顯要求最短路

如果按照自己建圖點個數爲(N^2) 明顯這個複雜度是不行的,過後,可以把每一層分成上個層進入點,和到下層的進入點,只需要把某一個邊變成C就可以了,比賽的時候收慘寫了2個u 到 v 沒寫v 到u 開始的時候tle了,然後單調隊列優化了下 ,就worng 了 結果wrong了一下午,後面發現有些層沒點,但是自己的代碼考慮到了,晚上才ac哎,
#include<cstdio>
#include<cstring>
#include<queue>
#include<deque>
#define inf 0x3f3f3f3f
#define M 700000
#define ll int
using namespace std;
struct G{
    ll head[M],en;
    struct E{
        ll u,v,next,cost;
    }e[M<<2];
    void init(){
        memset(head,-1,sizeof(head));en=0;
    }
    void add(ll u,ll v,ll cost){
        e[en].u=u;e[en].v=v;e[en].cost=cost;e[en].next=head[u];head[u]=en++;
    }
}g1;
ll dis[M];
bool vis[M];
ll realx(ll v,ll u,ll cost){
    if(dis[v]>dis[u]+cost){
        dis[v]=dis[u]+cost;
        return 1;
    }
    return 0;
}
deque<ll > q1;
ll spfa(ll sp,ll tp){
    memset(vis,1,sizeof(vis));
    memset(dis,inf,sizeof(dis));
    while(!q1.empty()) q1.pop_front();
    q1.push_back(sp);
    dis[sp]=0;vis[sp]=0;
    while(!q1.empty()){
        ll u=q1.front();q1.pop_front();
        for(ll i=g1.head[u];~i;i=g1.e[i].next){
            ll v=g1.e[i].v;ll cost=g1.e[i].cost;
            if(realx(v,u,cost)){
                if(vis[v]){
                    vis[v]=0;
                    if(!q1.empty()){
                        ll t1=q1.front();
                        if(dis[v]<dis[t1])
                        q1.push_front(v);
                        else q1.push_back(v);
                    }else q1.push_back(v);
                }
            }
        }
        vis[u]=1;
    }
    return dis[tp];
}
bool can_use[M];
int a1[M];
int main(){
    ll n,m,c,cas;
    while(~scanf("%d",&cas)){
        for(ll q=1;q<=cas;q++){
        scanf("%d%d%d",&n,&m,&c);
        g1.init();
        memset(can_use,0,sizeof(can_use));
        for(ll i=1;i<=n;i++){
            ll t1;scanf("%d",&t1);
            a1[i]=t1;
            g1.add(t1+n,i,c); //入邊
            g1.add(i,t1+2*n,c);// 出邊
            can_use[t1]=1;
        }
        for(int i=1;i<=n;i++){
            int t1=a1[i];
            if(t1==1) continue;
            if(can_use[t1-1]){
                g1.add(t1+2*n-1,i,0); //上層邊點
                g1.add(i,t1+n-1,0);   // 上層入邊
            }
        }
        for(ll i=0;i<m;i++){
            ll u,v,cost;scanf("%d%d%d",&u,&v,&cost);
            g1.add(u,v,cost);g1.add(v,u,cost);
        }
        ll ans=spfa(1,n);
        printf("Case #%d: ",q);
        if(ans!=dis[M-1])
        printf("%d\n",ans);
        else printf("-1\n");
        }
    }
    return 0;
}
/*
3
3 0 1
1 1 1
*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章