zoukankan      html  css  js  c++  java
  • codeforces 650C

    题解:

    如果没有相同数字,那么我们把每行按数值从小到大连边,每列按数值从小到大连边,边权为1,然后拓扑序DP一下,每个点的值就是最长路的长度

    现在有相同数字,怎么处理?

    考虑我们同一行同一列的相同数字连双向边(不需要两两连边,只需要使其连通就行),边权为0

    然后我们的图就变成了一个类似DAG但是里面有一堆边权为0并由双向边的连通块组成的东西。

    那么我们考虑缩点,缩掉边权为0的边,然后就是个DAG,拓扑序DP一下就好了。

      1 #include<bits/stdc++.h>
      2 #define pii pair<int,int>
      3 #define mp(a,b) make_pair(a,b)
      4 #define maxn 1000005
      5 using namespace std;
      6 int n,m;
      7 vector<vector<int>> a;
      8 vector<pii> b;
      9 struct edge
     10 {
     11     int to,next,w;
     12 }e[maxn<<2];
     13 int head[maxn<<1],p;
     14 void addedge(int u,int v,int w)
     15 {
     16     e[++p].to=v;e[p].w=w;e[p].next=head[u];head[u]=p;
     17 }
     18 int id(int x,int y)
     19 {
     20     return (x-1)*m+y;
     21 }
     22 int cnt;
     23 bool vis[maxn];
     24 int dis[maxn<<1],d[maxn<<1];
     25 vector<int> s[maxn<<1];
     26 int belong[maxn];
     27 void dfs(int u,int x)
     28 {
     29     s[x].push_back(u);
     30     for(int i=head[u];i;i=e[i].next)if(!e[i].w)
     31     {
     32         int v=e[i].to;
     33         if(!vis[v])vis[v]=1,dfs(v,x);
     34     }
     35 }
     36 void toposort()
     37 {
     38     queue<int> q;
     39     for(int i=1;i<=p;++i)if(e[i].w!=-1)d[e[i].to]++;
     40     for(int i=1;i<=cnt;++i)if(!d[i])q.push(i),dis[i]=1;
     41     while(!q.empty())
     42     {
     43         int u=q.front();q.pop();
     44         for(int i=head[u];i;i=e[i].next)if(e[i].w!=-1)
     45         {
     46             int v=e[i].to;
     47             dis[v]=max(dis[v],dis[u]+e[i].w);
     48             d[v]--;
     49             if(!d[v])q.push(v);
     50         }
     51     }
     52 }
     53 int main()
     54 {
     55     scanf("%d%d",&n,&m);
     56     cnt=n*m;
     57     vector<int> T;
     58     T.clear();a.push_back(T);
     59     for(int i=1;i<=n;++i)
     60     {
     61         T.clear();
     62         T.push_back(0);
     63         for(int j=1;j<=m;++j)
     64         {
     65             int x;scanf("%d",&x);
     66             T.push_back(x);
     67         }
     68         a.push_back(T);
     69     }
     70     for(int i=1;i<=n;++i)
     71     {
     72         b.clear();
     73         for(int j=1;j<=m;++j)b.push_back(mp(a[i][j],j));
     74         sort(b.begin(),b.end());
     75         for(int j=1;j<b.size();++j)
     76         {
     77             int u=id(i,b[j].second),v=id(i,b[j-1].second);
     78             if(b[j].first==b[j-1].first)addedge(v,u,0),addedge(u,v,0);
     79             else addedge(v,u,1);
     80         }
     81     }
     82     for(int j=1;j<=m;++j)
     83     {
     84         b.clear();
     85         for(int i=1;i<=n;++i)b.push_back(mp(a[i][j],i));
     86         sort(b.begin(),b.end());
     87         for(int i=1;i<b.size();++i)
     88         {
     89             int u=id(b[i].second,j),v=id(b[i-1].second,j);
     90             if(b[i].first==b[i-1].first)addedge(v,u,0),addedge(u,v,0);
     91             else addedge(v,u,1);
     92         }
     93     }
     94     for(int i=1;i<=n*m;++i)if(!vis[i])
     95     {
     96         dfs(i,++cnt);
     97         for(int j=0;j<s[cnt].size();++j)
     98         {
     99             int u=s[cnt][j];
    100             belong[u]=cnt;
    101         }
    102     }
    103     p=0;
    104     memset(head,0,sizeof(head));
    105     for(int i=1;i<=n;++i)
    106     {
    107         b.clear();
    108         for(int j=1;j<=m;++j)b.push_back(mp(a[i][j],j));
    109         sort(b.begin(),b.end());
    110         for(int j=1;j<b.size();++j)
    111         {
    112             int u=id(i,b[j].second),v=id(i,b[j-1].second);
    113             u=belong[u],v=belong[v];
    114             if(b[j].first!=b[j-1].first)addedge(v,u,1);
    115         }
    116     }
    117     for(int j=1;j<=m;++j)
    118     {
    119         b.clear();
    120         for(int i=1;i<=n;++i)b.push_back(mp(a[i][j],i));
    121         sort(b.begin(),b.end());
    122         for(int i=1;i<b.size();++i)
    123         {
    124             int u=id(b[i].second,j),v=id(b[i-1].second,j);
    125             u=belong[u];v=belong[v];
    126             if(b[i].first!=b[i-1].first)addedge(v,u,1);
    127         }
    128     }
    129     toposort();
    130     for(int i=n*m+1;i<=cnt;++i)
    131     {
    132         for(int j=0;j<s[i].size();++j)
    133         {
    134             int u=s[i][j];
    135             dis[u]=dis[i];
    136         }
    137     }
    138     int tot=0;
    139     for(int i=1;i<=n;++i)
    140     {
    141         for(int j=1;j<=m;++j)printf("%d ",dis[++tot]);
    142         puts("");
    143     }
    144     return 0;
    145 }
    View Code
  • 相关阅读:
    UVA10763交换学生
    UVA10763交换学生
    UVA10391复合词
    UVA10391复合词
    UVA10125和集
    UVA10125和集
    POJ3762 时间段用k次
    POJ3762 时间段用k次
    Win64 驱动内核编程-11.回调监控进线程句柄操作
    Win64 驱动内核编程-11.回调监控进线程句柄操作
  • 原文地址:https://www.cnblogs.com/uuzlove/p/10513805.html
Copyright © 2011-2022 走看看