• 计蒜客NOIP模拟赛(2)D1T3 深黑幻想


    【问题描述】
        凡终于发愤图强,决定专心搞OI,不再玩纸牌和坑钱了!没过多久就飘飘然了,总是陷入自己进了集训队的深黑幻想之中。
        样听说了之后,决定考一考凡欧拉回路怎么写。
    样:“我给你出一道题啊,是欧拉回路的,有N个点……”
        凡:“欧拉回路有什么卵用?你看Epacs不会写也能进集训队!”
        样:“他不会写欧拉回路,但他会做题啊,比如说这道题……
        “有N个点,M条奇怪的单向边,每个边有三个参数Ai,Bi,Ci,你可以指定这条边是从Ai连向Bi还是从Ai连向Ci,要求你构造一种方案使得把这M条边都指定完了之后,每个点的出度和入度相等!”
        凡:“这题我会做啊,但是这tmd和欧拉回路有什么关系?!”
    【输入格式】
    第一行两个正整数N,M,表示点的数目与边的数目
    接下来M行,每行三个正整数,代表Ai,Bi,Ci,含义如题目中所示
    【输出格式】
    输出一个长度为M的由01组成的字符串代表一个合法解
    其中第i个位置为0代表Ai向Bi连边,为1代表Ai向Ci连边
    如果有多组解,输出任意一组即可,保证存在合法解
    【样例输入】
    3 2
    1 2 3
    2 1 3
    【样例输出】
    00

    【数据范围与约定】

    测试点编号

    N,M

    特殊性质1

    1

    10


    2

    10


    3

    50

    4

    100

    5

    1000

    6

    10000


    7

    10000


    8

    50000


    9

    50000


    10

    50000


    特殊性质1: 保证所有的Ci=Bi+1

    对于所有数据,保证1<=Ai,Bi,Ci<=N,但是不保证AiBiCi互不相同

     

    这个题目的主要思想源于混合图求欧拉回路算法

    我们考虑一开始让Ai全部连向Bi,这样会有一些点度数不为0

    接下来建一张网络流图,由CiBi连边,源点向所有入度比出度大的点连边,

    所有出度比入度大的点向汇点连边。

    这样每有一个流量流过,就相当于将一条边由“Ai连向Bi”调整为“Ai连向Ci”

    最后我们只需要让程序自己去跑网络流检验一下输出方案即可

    相信有很多其他的网络流做法可以过掉这道题

     

    %%%%SAC大佬

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 struct Node
     9 {
    10     int next,to,dis;
    11 }edge[500001];
    12 int head[100001],num,cur[100001],dist[100001],n,m,du[100001];
    13 void add(int u,int v,int dis)
    14 {
    15     edge[num].next=head[u];
    16     edge[num].to=v;
    17     edge[num].dis=dis;
    18     head[u]=num++;
    19     edge[num].next=head[v];
    20     edge[num].to=u;
    21     edge[num].dis=0;
    22     head[v]=num++;
    23 }
    24 bool bfs(int S,int T)
    25 {
    26     int i;
    27     memset(dist,-1,sizeof(dist));
    28     queue<int>Q;
    29     Q.push(S);
    30     dist[S]=1;
    31     while (!Q.empty())
    32     {
    33         int u=Q.front();
    34         Q.pop();
    35          for (i=head[u];i!=-1;i=edge[i].next)
    36          {
    37             int v=edge[i].to;
    38              if (edge[i].dis>0&&dist[v]==-1)
    39              {
    40                 dist[v]=dist[u]+1;
    41                 Q.push(v);
    42              }
    43          }
    44     }
    45      if (dist[T]==-1) return 0;
    46        return 1;    
    47 }
    48 int dfs(int x,int flow,int des)
    49 {
    50     int res=0;
    51     if (flow<=0||x==des) return flow;
    52     for (int &i=cur[x];i!=-1;i=edge[i].next)
    53     {
    54         int v=edge[i].to;
    55         if (dist[v]==dist[x]+1&&edge[i].dis)
    56         {
    57             int tmp=dfs(v,min(flow-res,edge[i].dis),des);
    58             if (tmp<=0) continue;
    59             edge[i].dis-=tmp;
    60             edge[i^1].dis+=tmp;
    61             res+=tmp;
    62             if (res==flow) return res;
    63         }
    64     }
    65     return res;
    66 }
    67 int Max_flow()
    68 {
    69     int ans=0;
    70     while (bfs(0,n+1))
    71     {
    72         int a=0;
    73         memcpy(cur,head,sizeof(cur));
    74         while (a=dfs(0,2e9,n+1)) ans+=a;
    75     }
    76     return ans;
    77 }
    78 int main()
    79 {int i,a,b,c,tot=0;
    80     cin>>n>>m;
    81  memset(head,-1,sizeof(head));
    82     for (i=1;i<=m;i++)
    83     {
    84         scanf("%d%d%d",&a,&b,&c);
    85         add(c,b,1);
    86         du[b]--;du[a]++;
    87     }
    88     for (i=1;i<=n;i++)
    89      tot+=abs(du[i]);
    90     tot/=2;
    91      for (i=1;i<=n;i++)
    92      {
    93          if (du[i]>0) add(0,i,du[i]);
    94          else add(i,n+1,-du[i]);
    95      }
    96     if (Max_flow()==tot)
    97       for (i=1;i<=m;i++)
    98          printf("%d",edge[i*2-2].dis^1);
    99 }
  • 相关阅读:
    Android开发之适配器-ListView适配器的重复数据
    Android开发之TextView的下划线添加
    Android 自定义View修炼-Android开发之自定义View开发及实例详解
    Android 开发之自定义Dialog及UI的实现
    Android开发之ContentProvider(内容提供者)
    XC文件管理器(Android应用)
    高效 告别996,开启java高效编程之门 4-1普通码农与风骚码农资源关闭PK
    高效 告别996,开启java高效编程之门 4-2垃圾回收与物理资源释放
    高效 告别996,开启java高效编程之门 3-29实战案例五:排序
    高效 告别996,开启java高效编程之门 3-28实战案例四:分组
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7505015.html
Copyright © 2020-2023  润新知