• 一周总结08/30


    1.最短路变形

    【题意】给一个图,每条边有个距离和花费,要求创建一个子图,满足0点到其余点的距离总和最小,且边的总花费最小。

     【注意】首先,数组要开<<1大;

    其次,双关键字的最短路,即最小花费下最短路,要注意优先级就是贪心,可以在优先队列做文章,也可以直接在松弛判断当两条边相同,选择当前花费更加小的代价

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 500100;
    const int maxm = 1e6+10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    struct node
    {
        int u,v,w,nxt,val;
    }e[maxn<<2];
    int head[maxn];
    LL dis[maxn],cost[maxn];
    bool vis[maxn];
    int n,m,t,tot;
    void init()
    {
        tot=0;
        ms(head,-1);
        ms(dis,INF);
        ms(cost,INF);
        ms(vis,0);
    }
    void add(int u,int v,int w,int val)
    {
        e[tot].v=v;
        e[tot].w=w;
        e[tot].val=val;
        e[tot].nxt=head[u];
        head[u]=tot++;
    }
    void spfa()
    {
        queue<int> q;
        dis[0]=0; vis[0]=1; //cost[0]=0;
        q.push(0);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            vis[u]=0;
            for(int i=head[u]; i!=-1; i=e[i].nxt)
            {
                int v=e[i].v;
                int w=e[i].w;
                int val=e[i].val;
                if( dis[v]>dis[u]+w || ( dis[v]==dis[u]+w && cost[v]>val ) )
                {
                    dis[v]=dis[u]+w;
                    cost[v]=val;
                    if(!vis[v])
                    {
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            init();
            scanf("%d%d",&n,&m);
            for(int i=0;i<m;i++)
            {
                int u,v,w,val;
                scanf("%d%d%d%d",&u,&v,&w,&val);
                add(u,v,w,val);
                add(v,u,w,val);
            }
            spfa();
            LL s1=0,s2=0;
            for(int i=1;i<n;i++)
            {
                s1+=dis[i];
                s2+=cost[i];
            }
            printf("%lld %lld
    ",s1,s2);
        }
    }
    /*
    2
    4 5
    0 3 1 1
    0 1 1 1
    0 2 10 10
    2 1 1 1
    2 3 1 2
    4 5
    0 3 1 1
    0 1 1 1
    0 2 10 10
    2 1 2 1
    2 3 1 2
    
    */
    ZOJ K - Highway Project

    2.联通块DFS缩点 + BFS求隐式图最短路

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <list>
    #include <deque>
    #include <map>
    #include <set>
    using namespace std;
    #define ll long long
    const double PI = acos(-1.0);
    const int maxn = 101;
    const int INF = 0x3f3f3f3f;
    int T,n,m,tot,ans;
    char mp[maxn][maxn];
    int id[maxn][maxn];
    int vis[maxn*maxn];
    vector<int> edge[maxn*maxn];
    int dx[]={0,0,-1,1};
    int dy[]={-1,1,0,0};
    //http://acm.hnucm.edu.cn/vjudge/contest/view.action?cid=49#problem/F
    struct node
    {
        int x,step;
        node(int x,int step):x(x),step(step){};
    };
    
    void dfs(int x,int y)
    {
        char ch=mp[x][y];
        for(int i=0;i<4;i++)
        {
            int tx=x+dx[i];
            int ty=y+dy[i];
            if(tx>=0&&tx<n&&ty>=0&&ty<m&&!id[tx][ty]&&mp[tx][ty]==ch)
            {
                id[tx][ty]=tot;
                dfs(tx,ty);
            }
        }
    }
    
    
    void get_edge(int x,int y)
    {
        for(int i=0;i<4;i++)
        {
            int tx=x+dx[i];
            int ty=y+dy[i];
            if(tx>=0&&tx<n&&ty>=0&&ty<m&&id[tx][ty]!=id[x][y])
            {
                edge[id[x][y]].push_back(id[tx][ty]);
                edge[id[tx][ty]].push_back(id[x][y]);
            }
        }
    }
    
    int bfs(int st)
    {
        int res=-INF;
        memset(vis,0,sizeof(vis));
        queue<node> q;
        q.push(node(st,0));
        vis[st]=1;
        while(!q.empty())
        {
            node ed=q.front();
            q.pop();
            res=max(res,ed.step);
            for(int i=0;i<edge[ed.x].size(); i++)
            {
                if(!vis[edge[ed.x][i]])
                {
                    vis[edge[ed.x][i]]=1;
                    q.push(node(edge[ed.x][i], ed.step+1));
                }
            }
        }
        return res;
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            tot=1;
            ans=INF;
            memset(id,0,sizeof(id));
            scanf("%d%d",&n,&m);
            for(int i=0;i<=n*m;i++)
            {
                edge[i].clear();
            }
            for(int i=0;i<n;i++)
            {
                scanf("%s",mp[i]);
            }
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    if(!id[i][j])
                    {
                        id[i][j]=tot;
                        dfs(i,j);
                        tot++;
                    }
                }
            }
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    get_edge(i,j);
                }
            }
            for(int i=1;i<tot;i++)
                ans=min(ans,bfs(i));
            printf("%d
    ",ans);
        }
    }
    ZOJ 3781 Paint the Grid Reloaded
  • 相关阅读:
    android学习第一天
    定力
    C++ 虚基类表指针字节对齐
    c++内存对齐 转载
    #Pragma Pack(n)与内存分配
    c++ data语意学
    point类型·
    对象内存 (扩展 Data Structure Alignment)
    reinterpret_cast and const_cast
    static_cast AND dynamic_cast
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9557891.html
Copyright © 2020-2023  润新知