zoukankan      html  css  js  c++  java
  • P1525 关押罪犯【二分+二分图】

    输入输出样例

    输入 #1
    4 6
    1 4 2534
    2 3 3512
    1 2 28351
    1 3 6618
    2 4 1805
    3 4 12884

    思路

      对于要求最大值最小的问题,不难想到二分。

      在本题中,我们需要在 0 ~ 事件影响力的最大值 的范围内进行二分。

      确定了边界之后,就应该着手于写check函数。

      通过阅读题意可知,犯人之间有怨气值,相当于P3386之间的仰慕值,有两个监狱可以关押犯人,不在同一个监狱里的犯人不会干架。

      不难由此想到二分图的作用,把犯人分割成两个集合即可。

      对于此题来说,我们只要判定当前这个 mid 能不能使这张图被染色成一张 二分图 即可。

      白嫖了一组数据

      in.txt

      2 1
      1 2 28135

      out.txt

      0

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 template<class T>inline void read(T &res)
     10 {
     11     char c;T flag=1;
     12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     14 }
     15 
     16 namespace _buff {
     17     const size_t BUFF = 1 << 19;
     18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     19     char getc() {
     20         if (ib == ie) {
     21             ib = ibuf;
     22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     23         }
     24         return ib == ie ? -1 : *ib++;
     25     }
     26 }
     27 
     28 int qread() {
     29     using namespace _buff;
     30     int ret = 0;
     31     bool pos = true;
     32     char c = getc();
     33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     34         assert(~c);
     35     }
     36     if (c == '-') {
     37         pos = false;
     38         c = getc();
     39     }
     40     for (; c >= '0' && c <= '9'; c = getc()) {
     41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     42     }
     43     return pos ? ret : -ret;
     44 }
     45 
     46 const int maxn = 1e5 + 7;
     47 
     48 int cnt,n,m;
     49 int head[maxn << 1], edge[maxn << 1], nxt[maxn << 1];
     50 int w[maxn << 1], color[maxn];
     51 
     52 void BuildGraph(int u, int v, int c) {
     53     cnt++;
     54     edge[cnt] = v;
     55     nxt[cnt] = head[u];
     56     w[cnt] = c;
     57     head[u] = cnt;
     58 }
     59 
     60 bool check(int x) {
     61     queue <int> q;
     62     memset(color, 0, sizeof(color));
     63     for ( int j = 1; j <= n; ++j ) {
     64         //dbg(j);
     65         if(color[j])
     66             continue;
     67         else {
     68             q.push(j);
     69             color[j] = 1;
     70             while(!q.empty()) {
     71                 int u = q.front();
     72                 q.pop();
     73                 //dbg(u);
     74                 for (int i = head[u]; i; i = nxt[i]) {
     75                     int v = edge[i];
     76                     if(w[i] >= x) {
     77                         if(!color[v]) {
     78                             color[v] = (color[u] == 1 ? 2 : 1);
     79                             q.push(v);
     80                         }
     81                         else if(color[v] == color[u]) {
     82                             return false;
     83                         }
     84                     }
     85                 }
     86             }
     87         }
     88     }
     89     return true;
     90 }
     91 
     92 int main()
     93 {
     94     read(n);
     95     read(m);
     96     int maxx = 0;
     97     for ( int i = 1; i <= m; ++i ) {
     98         int u, v, c;
     99         read(u);
    100         read(v);
    101         read(c);
    102         BuildGraph(u,v,c);
    103         BuildGraph(v,u,c);
    104         maxx = max(maxx, c);
    105     }
    106 
    107     int l = 0, r = maxx;
    108     int mid = (l + r) >> 1;
    109 
    110     while(l <= r) {
    111         mid = (l + r) >> 1;
    112         //dbg(mid);
    113         if(check(mid)) {
    114             r = mid - 1;
    115         }
    116         else {
    117             l = mid + 1;
    118         }
    119     }
    120     if(l-1 < 0)
    121         l = 1;
    122     cout << l - 1 << endl;
    123     return 0;
    124 }
    View Code

     void dfs(int u, bool s) {
        visited[u] = true;
        side[u] = s;
        for(int v : edges[u]) {
            if(visited[v]) continue;
            dfs(v, !s);
        }
    }
     
    int main() {
        std::scanf("%d", &n);
        for(int i = 0; i < n - 1; ++i) {
            int u, v;
            std::scanf("%d%d", &u, &v);
            --u, --v;
            edges[u].push_back(v);
            edges[v].push_back(u);
            mat[u][v] = mat[v][u] = true;
        }
     
        dfs(0, false);
     
        int c1 = 0;
        for(int i = 0; i < n; ++i)
            c1 += side[i];
        if(c1 > n / 2)
            for(int i = 0; i < n; ++i)
                side[i] = !side[i];
         
        int cnt = 1;
        for(int i = 0; i < n; ++i) {
            if(!side[i]) continue;
            result[i] = MASK ^ (i64(1) << cnt) ^ 1;
            for(int v : edges[i])
                result[v] |= (i64(1) << cnt) | 1;
            ++cnt;
        }
         
        /*for(int i = 0; i < n - 1; ++i)
            for(int j = i + 1; j < n; ++j)
                if(mat[i][j] != ((result[i] | result[j]) == MASK))
                    std::cout << "Error: " << i << ' ' << j << std::endl;*/
     
        for(int i = 0; i < n; ++i)
            std::cout << result[i] << std::endl;
    }

  • 相关阅读:
    织梦dedecms上传漏洞uploadsafe.inc.php修复
    dedecms漏洞修复大全含任意文件上传漏洞与注入漏洞
    DEDECMS批量导入excel数据到后台文章系统的开发教程
    使用DEDE织梦计划任务功能定时更新首页
    如何解决织梦DedeCms文章标题字数长度限制的方法教程
    织梦后台点击网站主页跳转到../index.php?upcache=1删除方法
    dedecms漏洞修复大全含任意文件上传漏洞与注入漏洞
    dedecms模板中联动菜单高级使用技巧
    解决dede的loop中无法使用limit的方案+文章前数字序号
    DEDECMS 又一种隔行换色和分组加线的方法
  • 原文地址:https://www.cnblogs.com/orangeko/p/12337426.html
Copyright © 2011-2022 走看看