码迷,mamicode.com
首页 > 其他好文 > 详细

[黑科技]分层图

时间:2018-09-08 19:23:04      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:getc   inline   路径   裸题   node   tin   har   黑科技   make   

最近几天写了一些分层图的题目,来总结一下

分层图有一个很重要的性质:上一层不能到达下一层,但下一层能到达上一层

分层图常常结合最短路,所以叫分层图最短路,当然,也结合缩点之类的

[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;
}

[黑科技]分层图

标签:getc   inline   路径   裸题   node   tin   har   黑科技   make   

原文地址:https://www.cnblogs.com/owencodeisking/p/9610084.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!