• [SCU3453] Stock Charts


    题意:给出一个折线图,有N条线段,你想要把这些线段分成几个集合,使得每个集合中任意两条线段不相交

    题解:

    最小路径覆盖

    把每条线段当成一个点,若两条线段不相交则连一条边,则问题可转化为用最少的路径数使所有点都被经过,即为最小路径覆盖

    最小路径覆盖=N-二分图最大匹配

    注意:连边只能往一个方向连,即表示出两点的连通性即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 #define ll long long
     8 using namespace std;
     9 
    10 const int N = 110;
    11 
    12 int T,n,m,ans,tot;
    13 int a[N],b[N],dfn[N],s[N][30],g[N][N];
    14 bool vis[N];
    15 
    16 int gi() {
    17   int x=0,o=1; char ch=getchar();
    18   while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    19   if(ch=='-') o=-1,ch=getchar();
    20   while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    21   return o*x;
    22 }
    23 
    24 void init() {
    25   ans=0;
    26   memset(s,0,sizeof(s));
    27   memset(g,0,sizeof(g));
    28   memset(a,-1,sizeof(a));
    29   memset(b,-1,sizeof(b));
    30 }
    31 
    32 bool cmp(const int &x, const int &y) {
    33   return s[x][0]<s[y][0];
    34 }
    35 
    36 bool check(int u, int v) {
    37   for(int i=1; i<=m; i++) {
    38     if(s[u][i]>=s[v][i]) return false;
    39   }
    40   return true;
    41 }
    42 
    43 bool dfs(int u) {
    44   for(int i=1; i<=n; i++) {
    45     if(g[u][i] && !vis[i]) {
    46       vis[i]=1;
    47       if(dfs(b[i]) || b[i]==-1) {
    48     b[i]=u,a[u]=i;
    49     return true;
    50       }
    51     }
    52   }
    53   return false;
    54 }
    55 
    56 int main() {
    57   T=gi();
    58   while(T--) {
    59     init();
    60     n=gi(),m=gi();
    61     for(int i=1; i<=n; i++)
    62       for(int j=1; j<=m; j++) {
    63     s[i][j]=gi();
    64     s[i][0]=max(s[i][0],s[i][j]);
    65       }
    66     for(int i=1; i<=n; i++) dfn[i]=i;
    67     sort(dfn+1,dfn+n+1,cmp);
    68     for(int i=1; i<=n; i++) {
    69       int u=dfn[i],v;
    70       for(int j=i+1; j<=n; j++) {
    71     v=dfn[j];
    72     if(check(u,v)) g[u][v]=1;
    73       }
    74     }
    75     for(int i=1; i<=n; i++) {
    76       if(a[i]==-1) {
    77     memset(vis,0,sizeof(vis));
    78     if(dfs(i)) ans++;
    79       }
    80     }
    81     printf("Case #%d: %d
    ", ++tot,n-ans);
    82   }
    83   return 0;
    84 }
  • 相关阅读:
    nyoj--76--超级台阶
    nyoj--17--单调递增最长子序列
    poj-2406-Power Strings(KMP)
    poj-1611-The Suspects(并查集)
    poj 2031--Building a Space Station(prim)
    poj 3259-- Wormholes(SPFA)
    nyoj 21--三个水杯(隐式图bfs)
    HDU
    HDU
    CodeForces
  • 原文地址:https://www.cnblogs.com/HLXZZ/p/7573523.html
Copyright © 2020-2023  润新知