多校第16場 HDU 3998 Sequence(最多不相交路徑)

來源:互聯網
上載者:User

披著DP外衣的網路流

桂哥哥寫的沒有拆點的演算法居然AC了,結果我給他出了一個資料,結果就掛了,說明這題的資料給的太水了。。。

找到最長上升子序列,在所有的最長上升子序列中找到一種元素標號互不相同的情況,使序列個數做多

構圖方法:

將所有點拆點,保證其唯一性(在所有序列中只出現一次)

所有的DP為0,即可以做路徑起始點的和源點串連,DP為ans的點和匯點相連,邊權正無窮。

滿足dp[i]+1=dp[j]且a[i]<d[j]的兩點連一條正無窮的邊,這樣保證了每條可行流都是一條長度為ans+1的上升子序列,其他構圖方法有的能跑過資料,但是是錯的。

#include <cstdio>#include <cstring>#define max(a,b) (a>b?a:b)const int maxn=710;const int inf=5;const int s=0;struct edge{       int v,next,w;}edge[40005];int head[2*maxn],cnt;//for sapvoid addedge(int u, int v, int w){     edge[cnt].v=v;     edge[cnt].w=w;     edge[cnt].next=head[u];     head[u]=cnt++;     edge[cnt].v=u;     edge[cnt].w=0;     edge[cnt].next=head[v];     head[v]=cnt++;}int sap(int t){    int pre[2*maxn],cur[2*maxn],dis[2*maxn],gap[2*maxn];    int flow=0 , aug=inf ,u;    bool flag;    for (int i=0 ; i<=t ; ++i)    {        cur[i]=head[i];        gap[i]=dis[i]=0;    }    gap[s]=t+1;    u=pre[s]=s;    while (dis[s]<=t)    {          flag=0 ;          for (int &j=cur[u] ; ~j ; j=edge[j].next)          {              int v=edge[j].v;              if (edge[j].w>0 && dis[u]==dis[v]+1)              {                   flag=1;                   if(edge[j].w<aug)aug=edge[j].w;                   pre[v]=u;                   u=v;                   if (u==t)                   {                       flow+=aug;                       while (u!=s)                       {                             u=pre[u];                             edge[cur[u]].w-=aug;                             edge[cur[u]^1].w+=aug;                       }                       aug=inf;                   }                   break;              }          }          if (flag)continue ;          int mindis=t+1;          for (int j=head[u]; ~j ; j=edge[j].next)          {              int v=edge[j].v;              if (edge[j].w>0 && dis[v]<mindis)              {                 mindis=dis[v];                 cur[u]=j;              }          }          if(--gap[dis[u]]==0)break;          gap[dis[u]=mindis+1]++;          u=pre[u];    }    return flow;}void init (){     memset (head , -1 , sizeof(head));     cnt=0;}int n;int a[maxn];int dp[maxn];void build_graph(int len){    for (int i=0 ; i<n ; ++i)    {        addedge(i+1 , i+1+n , 1);        if(dp[i]==0)//只有DP為0才能作為路徑起點,否則會出現更長的序列,與最長子序列矛盾        {            addedge(0 , i+1 , inf);        }        if(dp[i]==len)//只有DP為len才能作為路徑終點        {            addedge(i+1+n , 1404 , inf);        }        for (int j=i+1 ; j<n ; ++j)        {            if(a[i]<a[j])            {                addedge(i+1+n , j+1 , inf);            }        }    }}int main (){    while (~scanf("%d",&n))    {        init();        for (int i=0 ; i<n ; ++i)        {            scanf("%d",a+i);        }        memset (dp , 0 , sizeof(dp));        for (int i=0 ; i<n ; ++i)        {            for (int j=0 ; j<i ; ++j)            {                if(a[i]>a[j])                dp[i]=max(dp[i],dp[j]+1);            }        }        int ans=0;        for (int i=0 ; i<n ; ++i)            ans=max(ans,dp[i]);        printf("%d\n",ans+1);        build_graph(ans);        printf("%d\n",sap(1404));    }    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.