poj 3160 Father Christmas flymouse (spfa + 强联通)
2013-01-12 22:13
302 查看
/* 样例给的太水,对题目理解毫无作用。 看了别人的报告才懂得。求最长路。有向图,可能有负边,也可能有环。 所以先缩点,把环缩成一个点。 */ #include<stdio.h> #include<string.h> #include<algorithm> #include<vector> #include<queue> using namespace std; struct node { int s,t,w; }; vector<node>edge[3001]; vector<int>e[3001]; int dis[3001],in[3001],out[3001],a[3001],b[150001],c[150001]; int stack[3001],instack[3001],dfn[3001],low[3001],fa[3001],num[3001];//num是缩点后,每个点的权值。fa是每个点缩点后,属于那个新的点 int n,m,y,ind,cnt; void init()//各种初始化 { memset(dfn,0,sizeof(dfn)); memset(stack,0,sizeof(stack)); memset(instack,0,sizeof(instack)); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(num,0,sizeof(num)); y=ind=cnt=0; int i; for(i=0;i<=3000;i++) { edge[i].clear(); e[i].clear(); } } void tarjan(int i)//强联通分量 模板 { int j,k; dfn[i]=low[i]=++ind; instack[i]=1; stack[y++]=i; for(j=0;j<e[i].size();j++) { k=e[i][j]; if(!dfn[k]) { tarjan(k); low[i]=min(low[i],low[k]); } else if(instack[k]) low[i]=min(low[i],dfn[k]); } if(low[i]==dfn[i]) { cnt++; int v; do { v=stack[--y]; instack[v]=0; fa[v]=cnt; num[cnt]+=(a[v]>0?a[v]:0);//缩点时,每个点,只加正的点的值 }while(v!=i); } } int spfa(int s) { int i,j; for(i=1;i<=cnt;i++) { dis[i]=0; } queue<int>q; q.push(s); while(!q.empty()) { int w=q.front(); q.pop(); for(j=0;j<edge[w].size();j++) { node p=edge[w][j]; if(dis[p.t]<dis[w]+p.w) { q.push(p.t); dis[p.t]=dis[w]+p.w; } } } int ans=0; for(i=1;i<=cnt;i++) { if(out[i]==0)//终点的出度为0; ans=max(ans,dis[i]); } return ans; } int main() { while(~scanf("%d%d",&n,&m)) { init(); int i,j; for(i=1;i<=n;i++) scanf("%d",&a[i]); for(i=1;i<=m;i++) { scanf("%d%d",&b[i],&c[i]); b[i]++;c[i]++; e[b[i]].push_back(c[i]); } for(i=1;i<=n;i++) { if(!dfn[i]) tarjan(i); } for(i=1;i<=m;i++) { int x=fa[b[i]]; int y=fa[c[i]]; if(x!=y) { in[y]++;out[x]++; node f; f.s=x;f.t=y;f.w=num[y]; edge[x].push_back(f); } } for(i=1;i<=cnt;i++)//加一个虚拟的起点0,0到任意入度为0的i点的权值是num[i]; { if(in[i]==0) { node g; g.s=0; g.t=i; g.w=num[i]; edge[0].push_back(g); } } printf("%d\n",spfa(0)); } return 0; }
相关文章推荐
- POJ 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse (SCC缩点+SPFA求最长路)
- POJ 3160 Father Christmas flymouse
- POJ - 3160 Father Christmas flymouse(最长路+强连通分量)
- POJ 3160 Father Christmas flymouse(强连通分量+spfa最长路)
- poj 3160 Father Christmas flymouse(强连通+dp)
- POJ 3160 Father Christmas flymouse Tarjon+DP
- POJ 3160 Father Christmas flymouse(强连通+DP)
- poj 3160 Father Christmas flymouse(强连通缩点+最长路)
- poj 3160 Father Christmas flymouse (强连通分量+记忆化搜素)
- poj 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse(Tarjan+SPFA)
- pku 3160 Father Christmas flymouse
- POJ 3160 Father Christmas flymouse
- poj 3160 Father Christmas flymouse 【SCC缩点 + 虚拟源点SPFA求最长路】
- POJ 3160 Father Christmas flymouse 解题报告
- POJ-3160-Father Christmas flymouse 解题报告
- 【连通图|强连通分量+dfs】POJ-3160 Father Christmas flymouse
- POJ3160 Father Christmas flymouse[强连通分量 缩点 DP]