zoukankan      html  css  js  c++  java
  • [POI 2008]Mafia

    这题目写了我好长时间,但还是几乎(不要在意细节)一遍 A 了喵~

    据说有代码奇短的,Orz 思路巧妙的大爷

    想我这种 Brute Force 写写的傻 X 真是代码量飞起来了耶,喵~

    如果把每个人看成点,每个人要 kill 的人向此人连出一条有向边,那么每个点仅有一条出边和一条入边

    经验告诉我们,这就是 环+内向图 的节奏

    经验又告诉我,处理这种图要么先暴力搞环,再搞挂在环上的树。要么先搞树,再弄环。

    此题显然是后者

    环+内向图只需要用 bfs 就可以搞出来了,看到写 tarjan 的真是 Orz 

    弄出 环 和 树 后,先在树上跑 dp,用 dp[u][0] 表示如果 u 最后被 kill 了,那么以 u 为根子树最少要死几人, dp[u][1] 是 u 存活下来的情况

    这是普及组难度的树形 dp 吧喵~

    再在环上跑 dp ,我们先破环为链,则有3种情况 (我们令在首的人为 A , 在尾的人为 B)

    1. A君 最后活着,那 B君 一定被 kill 了

    2. A君 最后被 kill 了,B君 存活了或也被 kill 了

    3. A君 存活了下来,B君 也存活了下来,然后 B君 kill A君

    三种情况要分类讨论

    中间过程的状态转移和以上三种情况类似,无非就是讨论 i 君 和 i+1 君 的是否被 kill 的关系  (妈妈说,某个字打出来是不好的喵~)

    被 kill 有两种可能:1.被自己的子树中的某君 kill 了  2.被环上的某君 kill 了

    这个 dp 也很好想嘛

    似乎除了难写就没有难度了喵?

      1 #include <cstdio>
      2 #include <cstring>
      3 const int size=1000001;
      4 const int inf=size;
      5 
      6 namespace IOspace
      7 {
      8     inline void assign() {freopen("isaac.in", "r", stdin); freopen("isaac.out", "w", stdout);}
      9     inline void close() {fclose(stdin); fclose(stdout);}
     10     inline int getint()
     11     {
     12         register int num=0;
     13         register char ch;
     14         do ch=getchar(); while (ch<'0' || ch>'9');
     15         do num=num*10+ch-'0', ch=getchar(); while (ch>='0' && ch<='9');
     16         return num;
     17     }
     18     inline void putint(int num, char ch='
    ')
     19     {
     20         char stack[15];
     21         register int top=0;
     22         if (num==0) stack[top=1]='0';
     23         for ( ;num;num/=10) stack[++top]=num%10+'0';
     24         for ( ;top;top--) putchar(stack[top]);
     25         if (ch) putchar(ch);
     26     }
     27 }
     28 
     29 int n;
     30 int g[size][2];
     31 int t, a[size];
     32 int f[size], d[size];
     33 int dp[size][2];
     34 bool vis[size], loop[size];
     35 
     36 struct edge {int point; edge * next;};
     37 edge MEM[size], * PORT=MEM;
     38 edge * E[size];
     39 inline edge * newedge(int _point, edge * _next)
     40     {edge * ret=PORT++; ret->point=_point; ret->next=_next; return ret;}
     41 
     42 inline int min(int x, int y) {return x<y?x:y;}
     43 inline int max(int x, int y) {return x>y?x:y;}
     44 inline void add(int & x, int y) {if (x>=inf || y>=inf) x=inf; else x+=y;}
     45 inline int search(int);
     46 inline int find(int);
     47 inline void bfs(int);
     48 
     49 int main()
     50 {
     51     int ans1=0, ans2=0;
     52 
     53     n=IOspace::getint();
     54     for (int i=1;i<=n;i++)
     55     {
     56         f[i]=IOspace::getint(), d[f[i]]++;
     57         if (f[i]==i) ans2++, vis[i]=1;
     58         E[f[i]]=newedge(i, E[f[i]]);
     59     }
     60 
     61     for (int i=1;i<=n;i++) if (!d[i])
     62     {
     63         vis[i]=1;
     64         ans2+=search(i);
     65     }
     66     for (int i=1;i<=n;i++) if (!vis[i])
     67     {
     68         vis[i]=1;
     69         ans2+=search(i);
     70     }
     71 
     72     memset(vis, 0, sizeof(vis));
     73     for (int i=1;i<=n;i++) if (!vis[i])
     74     {
     75         vis[i]=1;
     76         ans1+=find(i);
     77     }
     78 
     79     IOspace::putint(ans1, ' '); IOspace::putint(ans2);
     80 
     81     return 0;
     82 }
     83 inline int search(int x)
     84 {
     85     int ret=0;
     86     for (x=f[x];!vis[x];x=f[x]) vis[x]=1, ret++;
     87     return ret;
     88 }
     89 inline void bfs(int x)
     90 {
     91     static int l, r, q[size];
     92 
     93     l=r=0;
     94     for (q[r++]=x;l<r; )
     95     {
     96         int u=q[l++];
     97         for (edge * i=E[u];i;i=i->next)
     98             if (!loop[i->point])
     99             {
    100                 vis[i->point]=1;
    101                 q[r++]=i->point;
    102             }
    103     }
    104 
    105     for (int i=r-1;i>=0;i--)
    106         if (E[q[i]]==NULL) dp[q[i]][0]=inf;
    107         else if (E[q[i]]->next==NULL && loop[E[q[i]]->point]) dp[q[i]][0]=((E[q[i]]->point)==q[i])?1:inf;
    108         else
    109         {
    110             for (edge * j=E[q[i]];j;j=j->next)
    111                 if (!loop[j->point])
    112                     add(dp[q[i]][1], dp[j->point][0]);
    113             for (edge * j=E[q[i]];j;j=j->next)
    114                 if (!loop[j->point])
    115                     add(dp[q[i]][0], min(dp[j->point][0], dp[j->point][1]));
    116             add(dp[q[i]][0], 1);
    117         }
    118 }
    119 inline int find(int x)
    120 {
    121     int ret=0;
    122 
    123     vis[x]=1;
    124     for (x=f[x];!vis[x];x=f[x]) vis[x]=1;
    125     for (t=0;!loop[x];x=f[x]) loop[a[t++]=x]=1;
    126     for (int i=0;i<t;i++) bfs(a[i]);
    127     if (t==1) return dp[a[0]][0];
    128     g[0][1]=dp[a[0]][1]; g[0][0]=inf;
    129     for (int i=1;i<t;i++)
    130     {
    131         g[i][0]=min(g[i-1][0], g[i-1][1]);
    132         add(g[i][0], min(dp[a[i]][0], dp[a[i]][1]+1));
    133         g[i][1]=g[i-1][0];
    134         add(g[i][1], dp[a[i]][1]);
    135     }
    136     ret=g[t-1][0];
    137 
    138     g[0][0]=dp[a[0]][0]; g[0][1]=inf;
    139     for (int i=1;i<t;i++)
    140     {
    141         g[i][0]=min(g[i-1][0], g[i-1][1]);
    142         add(g[i][0], min(dp[a[i]][0], dp[a[i]][1]+1));
    143         g[i][1]=g[i-1][0];
    144         add(g[i][1], dp[a[i]][1]);
    145     }
    146     ret=min(ret, min(g[t-1][0], g[t-1][1]));
    147 
    148     g[0][0]=dp[a[0]][1]+1; g[0][1]=inf;
    149     for (int i=1;i<t;i++)
    150     {
    151         g[i][0]=min(g[i-1][0], g[i-1][1]);
    152         add(g[i][0], min(dp[a[i]][0], dp[a[i]][1]+1));
    153         g[i][1]=g[i-1][0];
    154         add(g[i][1], dp[a[i]][1]);
    155     }
    156     ret=min(ret, g[t-1][1]);
    157 
    158     return ret;
    159 }
    因为是考试时写的所以很长也是没办法的事系列
  • 相关阅读:
    十七、Java基础之final
    十六、Java基础之super
    十五、Java基础之多态
    十四、Java基础之方法重写/覆盖
    十三、Java基础之单例模式
    十二、Java基础之继承
    十一、Java基础之static关键字
    十、Java基础之this介绍
    九、Java基础之参数传递(值传递)
    利用ResultFilter实现asp.net mvc3 页面静态化
  • 原文地址:https://www.cnblogs.com/dyllalala/p/3899761.html
Copyright © 2011-2022 走看看