zoukankan      html  css  js  c++  java
  • [BZOJ4398] 福慧双修

    题面感人。。。

    求从1号点出发,经过至少另一个点,走的边不重复的最小简单环。

    发现对于简单环上和1号点相接的两个点的二进制表示上一定有至少一位不一样。

    我们就把它二进制分组,然后在dij的时候就可以看看当前的to如果是1的话现在的点如果是分在出发点区域的就不行。

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int N=40005;
    struct Node {int id,dis;bool operator < (const Node &rhs) const {return dis>rhs.dis;}};
    priority_queue<Node>q;
    int n,m,dis[N],ans,head[N],ecnt;
    struct Edge{int to,nxt,val;}e[N*5];
    void add(int bg,int ed,int val) {e[++ecnt]=(Edge){ed,head[bg],val};head[bg]=ecnt;}
    void dij(int a,int b) {
        memset(dis,0x3f,sizeof dis);
        for(int i=head[1];i;i=e[i].nxt) 
            if((e[i].to&a)==b) q.push((Node){e[i].to,e[i].val}),dis[e[i].to]=e[i].val;
        while(!q.empty()) {
            Node u=q.top();q.pop();
            if(u.dis!=dis[u.id]) continue;
            for(int i=head[u.id];i;i=e[i].nxt) {
                if(e[i].to==1) {
                    if((u.id&a)!=b)ans=min(ans,dis[u.id]+e[i].val); 
                    continue;
                }
                if(dis[u.id]+e[i].val<dis[e[i].to]) dis[e[i].to]=dis[u.id]+e[i].val,q.push((Node){e[i].to,dis[e[i].to]});
            }
        }
    }
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1,a,b,c,d;i<=m;i++) 
            scanf("%d%d%d%d",&a,&b,&c,&d),add(a,b,c),add(b,a,d);
        ans=0x3f3f3f3f;
        for(int i=1;i<=n;i<<=1) {
            dij(i,i);
            dij(i,0);
        }
        cout<<ans;
        return 0;
    }
    福慧双修
  • 相关阅读:
    深拷贝浅拷贝的探索以及实现
    Vue之动态class写法总结
    hh
    90%的新媒体人都在用的标题套路!
    研究999篇100W+爆款文,标题之总结
    想突破10w+?先过了这一关……
    易撰数据分析,做精准爆文分析!
    清除.bat
    截图.bat
    Git 学习笔记(二)分支管理
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9804351.html
Copyright © 2011-2022 走看看