hdu 3998 最大流 (最多不相交路径)
2012-10-11 14:51
525 查看
/* 类似于网络流24题中的一道(求最长上升子序列的最多个数): 构图方案: 首先求出LIS; 然后拆点 建边Edge(i,i+n,1) 因为没个点只能用一次,所以边的容量为1 然后对于每个dp[i]==1的建边Edge(s,i,1) dp[i]==k的建边Edge(i+n,t,1); dp[i]==dp[j]+1 建边Edge(j+n,i,1); 然后sap 求最大流就OK了 */ #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; #define M 10100 int gap[M],dis[M],pre[M],cur[M],dp[M]; int NE,NV,sink,source; int head[M],p[M],k,n; struct Node { int c,pos,next; } E[999999]; #define FF(i,NV) for(int i=0;i<NV;i++) int sap(int s,int t) { //memset(pre,-1,sizeof(pre)); memset(dis,0,sizeof(int)*(NV+1)); memset(gap,0,sizeof(int)*(NV+1)); FF(i,NV) cur[i] = head[i]; int u = pre[s] = s,maxflow = 0,aug = 1<<29; gap[0] = NV; while(dis[s] < NV) { loop: for(int &i = cur[u]; i != -1; i = E[i].next) { int v = E[i].pos; if(E[i].c && dis[u] == dis[v] + 1) { aug=min(aug,E[i].c); pre[v] = u; u = v; if(v == t) { maxflow += aug; for(u = pre[u]; v != s; v = u,u = pre[u]) { E[cur[u]].c -= aug; E[cur[u]^1].c += aug; } aug = 1<<29; } goto loop; } } int mindis = NV; for(int i = head[u]; i != -1 ; i = E[i].next) { int v = E[i].pos; if(E[i].c && mindis > dis[v]) { cur[u] = i; mindis = dis[v]; } } if( (--gap[dis[u]]) == 0)break; gap[ dis[u] = mindis+1 ] ++; u = pre[u]; } return maxflow; } void addEdge(int u,int v,int c ) { E[NE].c = c; E[NE].pos = v; E[NE].next = head[u]; head[u] = NE++; E[NE].c = 0; E[NE].pos = u; E[NE].next = head[v]; head[v] = NE++; } int LIS() { int i,j,ans=0; dp[1]=1; for(i=2;i<=n;++i) { dp[i]=1; for(j=1;j<i;++j) { if(p[j]<p[i]&&dp[j]>=dp[i])dp[i]=dp[j]+1; } ans=max(ans,dp[i]); } return ans; } int main() { int i,j; while(scanf("%d",&n)!=EOF) { NE=source=0; sink=n<<1|1; NV=sink+1; memset(head,-1,sizeof(head)); // memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { scanf("%d",&p[i]); } k=LIS(); for(i=1;i<=n;i++) { addEdge(i,i+n,1); if(dp[i]==1) addEdge(source,i,1); if(dp[i]==k) addEdge(i+n,sink,1); for(j=i+1;j<=n;++j) if(dp[j]==dp[i]+1)addEdge(i+n,j,n); } printf("%d\n%d\n",k,sap(source,sink)); } return 0; } /* 4 3 6 2 5 */
相关文章推荐
- hdu 3998 Sequence(DP+最大流,求最多的不相交路径)
- 多校第16场 HDU 3998 Sequence(最多不相交路径)
- [网络流24题] 06 最长递增子序列(最多不相交路径,最大流)
- [网络流24题] 最长递增子序列 (最多不相交路径---网络最大流)
- HDU-3998 Sequence 最多不相交上升子序列
- 网络流24题(06)最长递增子序列问题(最多不相交路径 + 最大流)
- 【网络流】HDU 3599 War 最多不相交路径
- 【网络流24题】 No.6 最长不减子序列问题 (最大流)[模型:最多不相交路径]
- ★ 最长递增子序列问题 (最多不相交路径)(分层思想) 网络流最大流
- 【网络流】 HDU 3998 Sequence 最多不重合路径
- HDU 1151 Air Raid(最小路径覆盖 = 顶点数 - 最大匹配数)
- HDU 1151Air Raid 最小路径覆盖=n-最大匹配量 (第二道二分匹配)
- hdu 3722 Card Game 求完全图中l个不相交的环的最大权和=最优匹配 KM算法
- HDU 4343 多查询求区间内的最大不相交区间个数-思维&贪心-卡时间&二分&剪枝
- HDU 3472 HS BDC 混合图欧拉路径 最大流
- 【网络流24题】No.11(航空路线问题 最长不相交路径 最大费用流)
- 匈牙利算法 hdu 1151有向图的最小路径覆盖=顶点数-最大匹配数
- HDU 3998 Sequence 最大流 isap 加 dp
- hdu 4606 Occupy Cities(线段相交+最小路径覆盖+二分)
- HDU 3998 Sequence 最长上升子序列+最大流