hdu 3998 Sequence 网络流

编程入门 行业动态 更新时间:2024-10-24 22:17:33

hdu 3998 Sequence <a href=https://www.elefans.com/category/jswz/34/1771439.html style=网络流"/>

hdu 3998 Sequence 网络流

题意:求一个序列最长上升子序列的长度以及有多少个最长上升子序列。

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define maxn 10000
#define INF 100000
struct Edge
{int from, to, cap, flow;
};int s, t;
int num;
int dp[maxn];
int ob[maxn];
vector<Edge> edges;    // 边数的两倍
vector<int> G[maxn];   // 邻接表,G[i][j]表示结点i的第j条边在e数组中的序号
bool vis[maxn];        // BFS使用
int d[maxn];           // 从起点到i的距离
int cur[maxn];         // 当前弧指针
int min(int a,int b)
{if(a<b) return a;else return b;
}
int max(int a,int b)
{if(a>b) return a;else return b;
}
void AddEdge(int from, int to, int cap)
{int len;Edge temp;temp.from=from;temp.to=to;temp.cap=cap;temp.flow=0;edges.push_back(temp);temp.from=to;temp.to=from;temp.cap=0;temp.flow=0;edges.push_back(temp);len = edges.size();G[from].push_back(len-2);G[to].push_back(len-1);
}
bool BFS()
{memset(vis, 0, sizeof(vis));queue<int> Q;Q.push(s);vis[s] = 1;d[s] = 0;while(!Q.empty()){int x = Q.front(); Q.pop();for(int i = 0; i < G[x].size(); i++){Edge& e = edges[G[x][i]];if(!vis[e.to] && e.cap > e.flow){vis[e.to] = 1;d[e.to] = d[x] + 1;Q.push(e.to);}}}return vis[t];
}
int DFS(int x, int a)
{if(x == t || a == 0) return a;int flow = 0, f;for(int& i = cur[x]; i < G[x].size(); i++){Edge& e = edges[G[x][i]];if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0){e.flow += f;edges[G[x][i]^1].flow -= f;flow += f;a -= f;if(a == 0) break;}}return flow;
}
int Maxflow()
{int flow = 0;while(BFS()){memset(cur, 0, sizeof(cur));flow += DFS(s, INF);}return flow;
}
int main()
{int i,j;while(scanf("%d",&num)!=EOF){int MAX=0;for(i=0;i<=2*num+10;i++) G[i].clear();for(i=1;i<=num;i++){scanf("%d",&ob[i]);AddEdge(i,i+num,1);}for(i=1;i<=num;i++) dp[i]=1;for(i=2;i<=num;i++)for(j=1;j<i;j++)if(ob[j]<ob[i])dp[i]=max(dp[i],dp[j]+1);for(i=1;i<=num;i++) if(dp[i]>MAX) MAX=dp[i];for(i=1;i<=num;i++)for(j=i+1;j<=num;j++)if(dp[i]+1==dp[j])AddEdge(i+num,j,1);s=0;t=num*2+1;for(i=1;i<=num;i++) if(dp[i]==1) AddEdge(0,i,1);for(i=1;i<=num;i++) if(dp[i]==MAX) AddEdge(i+num,t,1);//for(i=1;i<=num;i++) printf("%d ",dp[i]);printf("%d\n%d\n",MAX,Maxflow());}return 0;
}


 

 

转载于:.html

更多推荐

hdu 3998 Sequence 网络流

本文发布于:2024-02-07 00:33:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1752054.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:网络   hdu   Sequence

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!