zoukankan      html  css  js  c++  java
  • HIT暑期集训 图论基础

    C    CodeForces 938D

    建图+最短路。新建一个特别的节点,每个城市与这个特别节点之间加上一条长为该城市停留的花费a的边;然后对于题目给出每条边,将长度设置为原来长度乘以2(因为需要一来一回两次)加入图中。这样从新建节点到每个城市的最短路就是题目所求的最短花费了。用堆优化dij求单源最短路就行了。(好像新学了一点重载运算符相关的东西)

    (最近好像一直因为数组开错WA题。。啊这真是)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define maxn 200005
    #define maxm 600005
    #define inf 1e13
    using namespace std;
    typedef long long ll;
    int num,to[maxm],nxt[maxm],last[maxn],vis[maxn],n,m;
    ll w[maxm],dis[maxn];
    struct node
    {
        int num;
        ll dis;
        node(int x,ll y)
        {
            num=x;dis=y;
        }
        bool operator < (const node &a)const{return dis>a.dis;}
        //重载运算符< 
    };
    priority_queue<node>q;
    void add(int x,int y,ll z)
    {
        to[++num]=y;
        nxt[num]=last[x];
        last[x]=num;
        w[num]=z;
    }
    void dij(int s)
    {
        int i,x,y;
        for (i=1;i<=n+1;i++) 
        {
            dis[i]=inf;vis[i]=0;
        }
        dis[s]=0;
        q.push(node(s,0));
        while (!q.empty())
        {
            x=q.top().num;
            q.pop();
            if (vis[x]) continue;
            vis[x]=1;
            for (i=last[x];i;i=nxt[i])
            {
                y=to[i];
                if (dis[x]+w[i]<dis[y]) 
                {
                    dis[y]=dis[x]+w[i];
                    q.push(node(y,dis[y]));
                }
            }
        }
    }
    int main()
    {
        int i,j,x,y;
        ll z;
        scanf("%d%d",&n,&m);
        for (i=1;i<=m;i++)
        {
            scanf("%d%d%lld",&x,&y,&z);
            add(x,y,2*z);
            add(y,x,2*z);
        }
        for (i=1;i<=n;i++)
        {
            scanf("%lld",&z);
            add(n+1,i,z);
        }
        dij(n+1);
        for (i=1;i<=n;i++) printf("%lld ",dis[i]);
        return 0;
    }

    G    LibreOJ 2610

    对图求最大生成树,对于每组询问找LCA即可。(学着用了倍增求LCA,以为代码会比树链剖分短,但并没有。。)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 10005
    #define maxm 100005
    #define inf 99999999
    using namespace std;
    int w[maxn][22],fa[maxn][22],dep[maxn],vis[maxn];
    int num,to[maxm],nxt[maxm],last[maxn],wei[maxm];
    int f[maxn];
    struct edge
    {
        int from,to,w;
    }e[maxm];
    bool cmp(edge x,edge y){return x.w>y.w;}
    void add(int x,int y,int z)
    {
        to[++num]=y;
        nxt[num]=last[x];
        last[x]=num;
        wei[num]=z;
    }
    int find(int x)
    {
        if (x==f[x]) return x;
        return f[x]=find(f[x]);
    }
    void dfs(int x)
    {
        int i,y;
        vis[x]=1;
        for (i=last[x];i;i=nxt[i])
        {
            y=to[i];
            if (vis[y]) continue;
            dep[y]=dep[x]+1;
            w[y][0]=wei[i];
            fa[y][0]=x;
            dfs(y);
        }
    }
    int lca(int x,int y)
    {
        if (find(x)!=find(y)) return -1;
        int i,ans=inf;
        if (dep[x]>dep[y]) 
        {
            i=x;x=y;y=i;
        }
        for (i=20;i>=0;i--)
            if (dep[fa[y][i]]>=dep[x])
            {
                ans=min(ans,w[y][i]);
                y=fa[y][i];
            }    
        if (x==y) return ans;
        for(i=20;i>=0;i--)
        {
            if(fa[x][i]!=fa[y][i])
            {
                ans=min(ans,w[x][i]);
                ans=min(ans,w[y][i]);
                x=fa[x][i];
                y=fa[y][i];
            }
        }
        ans=min(ans,w[x][0]);
        ans=min(ans,w[y][0]);
        return ans;
    }
    int main()
    {
        int i,j,x,y,fx,fy,n,m,q;
        scanf("%d%d",&n,&m);
        for (i=1;i<=m;i++) scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].w);
        
        sort(e+1,e+m+1,cmp);
        for (i=1;i<=n;i++) f[i]=i;
        for (i=1;i<=m;i++)
        {
            x=e[i].from;
            y=e[i].to;
            fx=find(x);
            fy=find(y);
            if (fx!=fy)
            {
                f[fx]=fy;
                add(e[i].from,e[i].to,e[i].w);
                add(e[i].to,e[i].from,e[i].w);
            }
        }
        
        for (i=1;i<=n;i++)
        {
            if (vis[i]) continue;
            dep[i]=1;
            fa[i][0]=i;
            w[i][0]=inf;
            dfs(i);
        }
        for (i=1;i<=20;i++)
            for (j=1;j<=n;j++)
            {
                fa[j][i]=fa[fa[j][i-1]][i-1];
                w[j][i]=min(w[j][i-1],w[fa[j][i-1]][i-1]);
            }
        scanf("%d",&q);
        while (q--)
        {
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }

    H    UVA 11354

    I    UVA 10269

  • 相关阅读:
    装饰者模式
    NGUI研究院之三种方式监听NGUI的事件方法(七)
    unity3d连接数据库
    unity3d 连接MSSql
    Unity3D之游戏架构脚本该如何来写
    WCF 部署问题 小总结 (HTTP 不能注册的解决方法)
    Prototype
    web.config文件之自定义错误节
    asp:DropDownList与asp:DataList的联合使用
    剑指offer --合并链表
  • 原文地址:https://www.cnblogs.com/lsykk/p/13489091.html
Copyright © 2011-2022 走看看