[黑科技]分層圖


最近幾天寫了一些分層圖的題目,來總結一下

分層圖有一個很重要的性質:上一層不能到達下一層,但下一層能到達上一層

分層圖常常結合最短路,所以叫分層圖最短路,當然,也結合縮點之類的

[USACO09FEB]改造路Revamping Trails

雙倍經驗題[JLOI2011]飛行路線

這是一道分層圖最短路裸題

考慮\(dp\),\(dis[i][j]\)表示到達第\(i\)個點已經\(j\)次升級后所經過的最短路徑

那么就可以愉快的在\(Dijkstra\)里分類討論一下

\(Code\ Below:\)

#include <bits/stdc++.h>
#define mp make_pair
#define S second
#define F first
using namespace std;
const int maxn=10000+10;
const int maxm=50000+10;
int n,m,k,head[maxn],dis[maxn][21],vis[maxn][21],tot;
struct node{
    int to,next,val;
}e[maxm<<1];

inline int read(){
    register int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return (f==1)?x:-x;
}
inline void add(int x,int y,int w){
    e[++tot].to=y;
    e[tot].val=w;
    e[tot].next=head[x];
    head[x]=tot;
}
void Dijkstra(){
    memset(dis,0x3f3f3f3f,sizeof(dis));
    priority_queue<pair<int,pair<int,int> > > pq;
    pair<int,int> u;int v;
    dis[1][0]=0;pq.push(mp(0,mp(1,0)));
    while(!pq.empty()){
        u=pq.top().S;pq.pop();
        if(vis[u.F][u.S]) continue;
        vis[u.F][u.S]=1;
        for(int i=head[u.F];i;i=e[i].next){
            v=e[i].to;
            if(dis[v][u.S]>dis[u.F][u.S]+e[i].val){
                dis[v][u.S]=dis[u.F][u.S]+e[i].val;
                pq.push(mp(-dis[v][u.S],mp(v,u.S)));
            }
            if(u.S+1<=k&&dis[v][u.S+1]>dis[u.F][u.S]){
                dis[v][u.S+1]=dis[u.F][u.S];
                pq.push(mp(-dis[v][u.S+1],mp(v,u.S+1)));
            }
        }
    }
}


int main()
{
    n=read(),m=read(),k=read();
    int x,y,w;
    for(int i=1;i<=m;i++){
        x=read(),y=read(),w=read();
        add(x,y,w);add(y,x,w);
    }
    Dijkstra();
    printf("%d\n",dis[n][k]);
    return 0;
}

[USACO15JAN]草鑒定Grass Cownoisseur

這道題比剛剛那道麻煩一點

首先看到有環,縮點一下,重新建圖。把圖復制一遍,將第一層的\(to[i]\)向第二層的\(x\)連一條邊

\(Code\ Below:\)

#include <bits/stdc++.h>
#include <time.h>
#define inf 99999999
using namespace std;
const int maxn=100000+10;
int n,m,low[maxn],dfn[maxn],vis[maxn<<1],tim;
int head[maxn<<1],to[maxn<<2],nxt[maxn<<2],tot;
int col[maxn],siz[maxn<<1],color;
int x[maxn],y[maxn],dis[maxn<<1];
stack<int> s;
inline int read(){
    register int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return (f==1)?x:-x;
}
inline void add(int x,int y){
    to[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void tarjan(int u)
{
    low[u]=dfn[u]=++tim;
    vis[u]=1;s.push(u);
    for(int i=head[u];i;i=nxt[i]){
        int v=to[i];
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else if(vis[v]) low[u]=min(low[u],dfn[v]);
    }
    if(low[u]==dfn[u]){
        color++;
        while(s.top()!=u){
            vis[s.top()]=0;
            col[s.top()]=color;
            siz[color]++;
            s.pop();
        }
        vis[u]=0;col[u]=color;siz[color]++;s.pop();
    }
}

int main()
{
    n=read(),m=read();
    for(int i=1;i<=m;i++){
        x[i]=read(),y[i]=read();
        add(x[i],y[i]);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i]) tarjan(i);
    memset(head,0,sizeof(head));
    memset(to,0,sizeof(to));
    memset(nxt,0,sizeof(nxt));
    memset(vis,0,sizeof(vis));
    tot=0;
    for(int i=1;i<=m;i++)
        if(col[x[i]]!=col[y[i]]){
            add(col[x[i]],col[y[i]]);
            add(col[x[i]]+color,col[y[i]]+color);
            add(col[y[i]],col[x[i]]+color);
        }
    for(int i=1;i<=color;i++) siz[i+color]=siz[i];
    queue<int> q;
    vis[col[1]]=1;
    q.push(col[1]);
    while(!q.empty()){
        int u=q.front();q.pop();vis[u]=0;
        for(int i=head[u];i;i=nxt[i]){
            int v=to[i];
            if(dis[v]<dis[u]+siz[u]){
                dis[v]=dis[u]+siz[u];
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    printf("%d\n",dis[col[1]+color]);
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM