您的位置:首页 > Web前端

POJ 3592 Instantaneous Transference

2011-01-19 16:40 330 查看
对于别人来说很水的题,对我来说很难。。。唉

首先,这道题抽象成一张有向图,由于magic power的存在,使得这张图中存在环,于是想到用强连通分量缩点的方法,把这张图变成DAG图(有向无环图),把每个分量中各个点的权值累加(注意可能为0)

然后从左上角的点所在的分量开始,求一条最长的一条带权路径,有很多方法,网上说的有拓扑排序,Bellman-Ford(运用记忆化搜索),DFS等等,由于数据量小,我就用了拍起来比较简单的DFS

这道题又被读题给害了, in the order from north to south then west to east我以为是逐列扫描,但事实上竟然是逐行扫描,鄙视下自己的英语。。。

不过A了这道题后,收获还是很多,也更加喜欢邻接表了,嘿嘿

代码:

#include<iostream>
#include<queue>
#include<stack>
using namespace std;
const int MAX=1605;
struct node
{
int v,next;
}g[MAX*100],path[MAX*100];
int dfn[MAX],low[MAX],inStack[MAX],belong[MAX],adj[MAX],adj2[MAX],value[MAX];
char map[45][45];
int x[MAX],y[MAX],mat[45][45],vis[MAX],v[MAX];
int n,m,e,ee,index,cnt,maxx;
stack<int>s;
void add(int u,int v)
{
g[e].v=v; g[e].next=adj[u]; adj[u]=e++;
}
void add2(int u,int v)
{
path[ee].v=v; path[ee].next=adj2[u]; adj2[u]=ee++;
}
void dfs(int u,int sum)
{
maxx=max(sum,maxx);
vis[u]=1;
for(int i=adj2[u];i!=-1;i=path[i].next)
{
if(!vis[path[i].v])
{
dfs(path[i].v,sum+value[path[i].v]);
}
}
vis[u]=0;
}
void tarjan(int u)
{
int v,i;
dfn[u]=low[u]=++index;
s.push(u);
inStack[u]=1;
for(i=adj[u];i!=-1;i=g[i].next)
{
v=g[i].v;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(inStack[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
cnt++;
do
{
v=s.top();
s.pop();
belong[v]=cnt;
inStack[v]=0;
}while(u!=v);
}
}
int main()
{
int i,j,k,a,b,T;
scanf("%d",&T);
while(T--)
{
memset(dfn,0,sizeof(dfn));
memset(inStack,0,sizeof(inStack));
memset(adj,-1,sizeof(adj));
memset(adj2,-1,sizeof(adj));
e=cnt=ee=index=0;
scanf("%d%d",&n,&m);
getchar();
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
scanf("%c",&map[i][j]);
getchar();
}
k=0;
memset(mat,0,sizeof(mat));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(map[i][j]>='0'&&map[i][j]<='9')
v[(i-1)*m+j]=map[i][j]-'0';
else
{
if(map[i][j]=='*')
mat[i][j]=++k;
v[(i-1)*m+j]=0;
}
}
}
for(i=1;i<=k;i++)
{
scanf("%d%d",&x[i],&y[i]);
x[i]++;
y[i]++;
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(map[i][j]=='#')
continue;
k=(i-1)*m+j;
if(j!=m&&map[i][j+1]!='#')
{
add(k,k+1);
}
if(i!=n&&map[i+1][j]!='#')
{
add(k,k+m);
}
if(map[i][j]=='*'&&map[x[mat[i][j]]][y[mat[i][j]]]!='#')
{
a=(x[mat[i][j]]-1)*m+y[mat[i][j]];
add(k,a);
}
}
}
while(!s.empty())
s.pop();
for(i=1;i<=m*n;i++)
{
if(!dfn[i])
tarjan(i);
}
memset(value,0,sizeof(value));
for(i=1;i<=m*n;i++)
value[belong[i]]+=v[i];
for(j=1;j<=m*n;j++)
{
for(i=adj[j];i!=-1;i=g[i].next)
{
a=belong[j];
b=belong[g[i].v];
if(a==b)
continue;
add2(a,b);
}
}
memset(vis,0,sizeof(vis));
maxx=-1;
dfs(belong[1],value[belong[1]]);
printf("%d/n",maxx);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: