[BZOJ1093][ZJOI2007]最大半连通子图
来源:互联网 发布:卸载软件下载 编辑:程序博客网 时间:2024/04/29 03:57
先缩点,就转化成了求一条最长链和求有多少条这样的最长链。
关键是第二个的dp,设dp[i]表示到第i个点,有多少条最长路经过它,那么
#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<iostream>#include<string>#include<cassert>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<climits>#define X first#define Y second#define DB double#define MP make_pair#define LL long long#define pb push_back#define sqr(_) ((_)*(_))#define INF 0x3f3f3f3f#define pii pair<int,int>#define pdd pair<DB,DB>#define ull unsigned LL#define DEBUG(...) fprintf(stderr,__VA_ARGS__)using namespace std;const int MAXN=100000+10,MAXM=1000000+10;struct Graph{ int first[MAXN],next[MAXM],to[MAXM],size[MAXN],deg[MAXN]; int sccno[MAXN],e,scc_cnt,pre[MAXN],low[MAXN],dfs_clock; stack<int> st; Graph(){ memset(first,-1,sizeof(first)); memset(size,0,sizeof(size)); memset(pre,0,sizeof(pre)); memset(low,0,sizeof(pre)); memset(deg,0,sizeof(deg)); e=scc_cnt=dfs_clock=0; } void add(int a,int b) { next[e]=first[a];first[a]=e;to[e]=b;++e;deg[b]++; } void tarjan(int u) { pre[u]=low[u]=++dfs_clock; st.push(u); for(int i=first[u];i!=-1;i=next[i]) { int v=to[i]; if(!pre[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(!sccno[v]) low[u]=min(low[u],pre[v]); } if(low[u]==pre[u]) { ++scc_cnt; while(!st.empty()) { int x=st.top();st.pop(); sccno[x]=scc_cnt; size[scc_cnt]++; if(x==u) break; } } }}G[2];int n,m;int x,dp[2][MAXN],vis[MAXN];vector<int> c;void build(){ Graph* it=&G[0]; for(int i=1;i<=n;i++)//Warning { for(int j=it->first[i];j!=-1;j=it->next[j]) { int v=it->to[j]; if(it->sccno[i]!=it->sccno[v]) G[1].add(it->sccno[i],it->sccno[v]); } //DEBUG("%d\n",c.size()); } G[1].scc_cnt=G[0].scc_cnt; memcpy(G[1].size,G[0].size,sizeof(G[0].size));}void work1(){ queue<int> q; Graph* it=&G[1]; for(int i=1;i<=it->scc_cnt;i++) { if(!it->deg[i]) { q.push(i); dp[0][i]=it->size[i]; dp[1][i]++; } } while(!q.empty()) { int u=q.front();q.pop(); for(int i=it->first[u];i!=-1;i=it->next[i]) { int v=it->to[i]; it->deg[v]--; if(!it->deg[v]) q.push(v); if(vis[v]==u)continue; vis[v]=u; if(dp[0][u]+it->size[v]>dp[0][v]) { dp[0][v]=dp[0][u]+it->size[v]; dp[1][v]=dp[1][u]; } else if(dp[0][u]+it->size[v]==dp[0][v]) { dp[1][v]+=dp[1][u]; dp[1][v]%=x; } } } int ans1=0,ans2=0; for(int i=1;i<=it->scc_cnt;i++) ans1=max(ans1,dp[0][i]); for(int i=1;i<=it->scc_cnt;i++) if(dp[0][i]==ans1) { ans2+=dp[1][i]; ans2%=x; } cout<<ans1<<endl<<ans2<<endl;}int main(){#ifndef ONLINE_JUDGE freopen("g.in","r",stdin); freopen("g.out","w",stdout);#endif scanf("%d %d %d",&n,&m,&x); for(int i=1;i<=m;i++) { int a,b; scanf("%d %d",&a,&b); G[0].add(a,b); } for(int i=1;i<=n;i++) if(!G[0].pre[i]) G[0].tarjan(i); build(); work1();}
0 0
- [bzoj1093][ZJOI2007]最大半连通子图
- bzoj1093【ZJOI2007】最大半连通子图
- [BZOJ1093][ZJOI2007]最大半连通子图
- 【bzoj1093】 [ZJOI2007]最大半连通子图
- BZOJ1093: [ZJOI2007]最大半连通子图
- BZOJ1093: [ZJOI2007]最大半连通子图
- bzoj1093: [ZJOI2007]最大半连通子图
- BZOJ1093 [ZJOI2007]最大半连通子图
- 【BZOJ1093】[ZJOI2007]最大半连通子图【SCC】【DAG】【DP】
- Tarjan-bzoj1093: [ZJOI2007]最大半连通子图
- [bzoj1093][ZJOI2007]最大半连通子图 Tarjan,DP
- 【BZOJ1093】【ZJOI2007】最大半连通子图 强连通分量缩点+sort去重边+拓扑排序
- bzoj1093 最大半连通子图
- [BZOJ1093][ZJOI2007]最大半连通子图 强联通+拓扑排序+dp 做题笔记
- bzoj1093[ZJOI2007]最大半连通子图 tarjan+拓补排序
- BZOJ1093 [ZJOI2007]最大半连通子图 【tarjan缩点 + DAG最长路计数】
- [BZOJ1093][ZJOI2007][Tarjan][DP]最大半联通子图
- 【bzoj1093】【zjoi2007】【最大半联通子图】【缩点+dp】
- struts2+hibernate流程
- Linux su - root无法登陆 :No such file or directory
- textField设置placeholder的字体大小,颜色等
- MongoDB简单测试
- iOS中 HTTP Socket TCP IP通信协议详解
- [BZOJ1093][ZJOI2007]最大半连通子图
- s2sh框架搭建心得
- Linux命令——chmod(修改读写执行等权限)
- 获取客户端IP和MAC地址工具类
- 第一行代码笔记之七高级技巧
- JS继承的实现及公有、私有、静态方法的书写
- HTML5语义化元素
- 《大明王朝的七张面孔》——海瑞
- Android 驱动USB摄像头