poj 3160 Father Christmas flymouse (SCC缩点+SPFA求最长路)
来源:互联网 发布:windows自带桌面图片 编辑:程序博客网 时间:2024/05/18 01:46
题目大意:一个有向图,每个顶点有一个权值(可正可负),现在从某个顶点出发,求所能获得的最大权值。当经过某个顶点时可以选择加上该顶点的权值或者不加,且一个顶点的权值只能够被加一次,顶点可重复访问。
建模:显然对于权为负的顶点是不加的,对于一个强连通分支,要使获得的权值最大,所有的正权都应当算上。于是可以把原图进行缩点,对于每一个强连通分量其权值为内部点的正权值之和。缩点后得到一个DAG图,用SPFA求最长路即可。这里有个技巧,就是加一个源点,另其权值为0,对于DAG图每个顶点连一条边。这样只需以该源点为起点,求一次SPFA就可以得到从各个顶点出发获得的最大值。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<stack>#include<queue>using namespace std;#define N 30005struct Edge{ int to,next;}edge[150005];int cnt,head[N],low[N],dfn[N],dfs_clock,scc_cnt,sccno[N],val[N],v[N];vector<int>scc[N];stack<int>S;void dfs(int u){ low[u]=dfn[u]=++dfs_clock; S.push(u); for(int i=head[u];~i;i=edge[i].next){ int v=edge[i].to; if(!dfn[v]){ dfs(v); low[u]=min(low[v],low[u]); } else if(!sccno[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]){ val[++scc_cnt]=max(0,v[u]); for(;;){ int x=S.top();S.pop(); sccno[x]=scc_cnt; if(x==u) break; val[scc_cnt]+=max(0,v[x]); } }}void find_scc(int n){ memset(sccno,0,sizeof(sccno)); memset(dfn,0,sizeof(dfn)); dfs_clock=scc_cnt=0; for(int i=0;i<n;++i) if(!dfn[i]) dfs(i);}inline void add(int u,int v){ edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt++;}vector<int>G[N];bool inq[N];int d[N];void spfa(int s){ queue<int>q; memset(inq,0,sizeof(inq)); memset(d,0,sizeof(d)); inq[s]=1;q.push(s); while(!q.empty()){ int u=q.front();q.pop(); inq[u]=0; for(int i=0;i<G[u].size();++i){ int v=G[u][i]; if(d[u]+val[v]>d[v]){ d[v]=d[u]+val[v]; if(!inq[v]){ inq[v]=1; q.push(v); } } } }}int main(){ int i,j,n,m,x,y; while(~scanf("%d%d",&n,&m)){ memset(head,-1,sizeof(head)); cnt=0; for(i=0;i<n;++i) scanf("%d",&v[i]); for(i=0;i<m;++i){ scanf("%d%d",&x,&y); add(x,y); } find_scc(n); for(i=1;i<=scc_cnt;++i) {G[i].clear();d[i]=-1;} for(i=0;i<n;++i) for(j=head[i];~j;j=edge[j].next){ int v=edge[j].to; if(sccno[i]!=sccno[v]) G[sccno[i]].push_back(sccno[v]); } for(i=1;i<=scc_cnt;++i) G[scc_cnt+1].push_back(i); int ans=-1; spfa(scc_cnt+1); for(i=1;i<=scc_cnt;++i) ans=max(ans,d[i]); printf("%d\n",ans); } return 0;}
0 0
- poj 3160 Father Christmas flymouse (SCC缩点+SPFA求最长路)
- poj 3160 Father Christmas flymouse 【SCC缩点 + 虚拟源点SPFA求最长路】
- POJ 3126 --Father Christmas flymouse【scc缩点构图 && SPFA求最长路】
- POJ 3160 Father Christmas flymouse tarjan缩点+spfa求最长路
- POJ--3160[Father Christmas flymouse] 缩点+SFPA求最长路
- POJ 3160 Father Christmas flymouse 强连通缩点+spfa最长路
- POJ 3160 Father Christmas flymouse(强连通分量+spfa最长路)
- 【POJ】3160 Father Christmas flymouse 强连通+最长路
- POJ 3160 Father Christmas flymouse 强连通+最长路
- poj 3160 Father Christmas flymouse(强连通缩点+最长路)
- POJ 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse (spfa + 强联通)
- poj 3160 Father Christmas flymouse(Tarjan+SPFA)
- POJ 3160 — Father Christmas flymouse 强连通+spfa
- MySQL分表
- 免安装sql使用
- 排序3-堆排序
- 新锐房地产销售管理系统(部分流程)技术解析(十) 销售管理_销售优惠设置
- WireShark抓包后统计
- poj 3160 Father Christmas flymouse (SCC缩点+SPFA求最长路)
- C++常用计算几何算法
- SPDL: SHGetSpecialFolderLocation()、SHGetFileInfo()、SHGetPathFromIDList()函数
- Android View的刷新机制
- 使用jTopo给Html5 Canva中绘制的元素添加鼠标事件_html5教程技巧
- 通过VMware Fusion将 Mac 中的文件夹共享到虚拟机
- javaweb JDBC 数据库连接mysql 配置代码 (直接可用)
- jQuery注意事项及技巧
- 关于坐标系