10
2
2010
0

POJ3592 回来后做的第一题

swain[王雨舟](394528923) 22: wudiswain[王雨舟](394528923) 22:25:50
一张地图上,有一些矿点,每个矿点上都一个一定数量的矿(每个矿的量不一定相同) ,图上有些点可能是障碍物,现在坦克从图的左上角出发,出口在右下角,坦克只能往右或者往下开,问最多能有得到多少矿点,坦克开过矿点后矿点的矿全部给坦克
wudisplay[bsed刘通](357240143) 22:26:17
费用流?
wudiswain[王雨舟](394528923) 22:26:20
各位大牛,赶紧秒杀了这个。。
wudiswain[王雨舟](394528923) 22:26:34
。。费..
wudisplay[bsed刘通](357240143) 22:26:41
没描述啊
wudiswain[王雨舟](394528923) 22:26:51
坦克从图的左上角出发,出口在右下角,坦克只能往右或者往下开
wudisplay[bsed刘通](357240143) 22:27:06
DP就行了吧?
wudiswain[王雨舟](394528923) 22:27:11

wudiswain[王雨舟](394528923) 22:27:15
这是问题一
wudiswain[王雨舟](394528923) 22:27:26
还有改进版的
wudiswain[王雨舟](394528923) 22:27:33
现在图上有一些传送门
wudisplay[bsed刘通](357240143) 22:27:32

wudiswain[王雨舟](394528923) 22:27:44
每个传送门指定到图上 的一个点
wudiswain[王雨舟](394528923) 22:27:54
现在问你最多能有多少矿
wudiswain[王雨舟](394528923) 22:28:14
各位观众赶紧来秒杀这个
wudisplay[bsed刘通](357240143) 22:28:21
擦,这不是你问过小红的嘛
wudiswain[王雨舟](394528923) 22:28:39
。。擦,我哈尔滨回来后今天花了一天才AC
wudisplay[bsed刘通](357240143) 22:28:58
这种题,给他们说有意义么...反正我不会
wudiwudiswain[王雨舟](394528923) 22:29:31
。。我只是想说,不搞ACM的话,类似这种东西是很难写的。。
wudisplay[bsed刘通](357240143) 22:29:36

wudiswain[王雨舟](394528923) 22:29:47
刘大牛。。你怎么可能不会
wudisplay[bsed刘通](357240143) 22:29:48
果然比我有远见
wudiswain[王雨舟](394528923) 22:30:25
我只是想让听众有点兴趣而已
wudiswain[王雨舟](394528923) 22:30:37
方帧去哪了

先将所有矿点缩点,然后求最长路

//boatswain 2010 /10/ 1
//*********************************
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
const int N=25000;
int n,m,ans;
char map[50][50];
int loc[50][50];
int door[N];
int doornum;
int block[N];
int blocknum;
int ore[N];
int orenum;
//tarjan()
int scc,index,dfn[N],low[N],belong[N],num[N],sstack[N],top,out[N];
bool instack[N];
struct Edge{
	int v,next;
}edge[N];
int cnt;
int head[N];
int sum[N];
bool oyes(int i,int j){
	if (i>=0&&i<n&&j>=0&&j<m&&map[i][j]!='#')	return true;
	return false;
}
void addedge(int u,int v){
	edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;
}
struct Edge2{
	int v,next,val;
}e[N];
int aug;
int head2[N];
void addedge2(int u,int v,int val){
	e[aug].v=v;
	e[aug].val=val;
	e[aug].next=head2[u];
	head2[u]=aug++;
}
void init(){
	aug=cnt=doornum=blocknum=orenum=0;
	memset(head,-1,sizeof(head));
	memset(head2,-1,sizeof(head));
	memset(block,0,sizeof(block));
	memset(loc,0,sizeof(loc));
	memset(map,0,sizeof(map));
	memset(ore,0,sizeof(ore));
	scanf("%d%d",&n,&m);
	for (int i=0;i<n;i++)  scanf("%s",map[i]);
	for (int i=0;i<n;i++)	
		for (int j=0;j<m;j++){
			loc[i][j]=i*m+j;
			if (map[i][j]=='*')		door[doornum++]=i*m+j;
			else if (map[i][j]=='#')	block[blocknum++]=i*m+j;
			else ore[loc[i][j]]=map[i][j]-'0';
		}
	for (int i=0;i<n;i++)
		for (int j=0;j<m;j++){
			if (!oyes(i,j)) continue;
			if (oyes(i+1,j)) addedge(loc[i][j],loc[i+1][j]);
			if (oyes(i,j+1)) addedge(loc[i][j],loc[i][j+1]);
		}
	for (int i=0;i<doornum;i++){
		int a,b;	scanf("%d%d",&a,&b);
		if (oyes(a,b)) addedge(door[i],loc[a][b]);
	}
}
int MAX(int a,int b){
    if (a<b) return b;
    return a;
}
int MIN(int a,int b){
    if(a<b)
        return a;
    return b;
}
void tarjan(int u)
{
    dfn[u]=low[u]=++index;
    sstack[++top]=u;
    instack[u]=true;
    for (int j=head[u];j!=-1;j=edge[j].next){
        int v=edge[j].v;
        if(dfn[v]==0){
            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])
    {
        scc++;
        while(1)
        {
            int tmp=sstack[top--];
            instack[tmp]=0;
            belong[tmp]=scc;
            num[scc]++;
            if(tmp==u)
                break;
        }
    }
}
void SPFA(){
		bool vis[N];
		int dist[N],l,r,q[N*10],MAXQ=N+5;
		for (int i=0;i<scc+1;i++){
			dist[i]=-1;
			vis[i]=false;
		}
		l=r=0;
		q[r++]=0;
		dist[0]=0;
		while (l!=r){
			int u=q[l++];l%=MAXQ;
			vis[u]=false;
			for (int j=head2[u];j!=-1;j=e[j].next){
				int v=e[j].v;
				if (dist[v]<dist[u]+e[j].val){
					dist[v]=dist[u]+e[j].val;
				    if (!vis[v]){             
                       vis[v]=true; q[r++]=v;r%=MAXQ;
                       }
                }
		}
		}
		ans=0;
		for (int i=1;i<scc+1;i++){
            ans=MAX(ans,dist[i]);
            }
			
}
void solve(){
	scc=top=index=0;
	memset(dfn,0,sizeof(dfn));
	memset(sum,0,sizeof(sum));
	for (int i=0;i<n*m;i++)
		if (!dfn[i]) tarjan(i);
	for (int i=0;i<n*m;i++)
		sum[belong[i]]+=ore[i];
	addedge2(0,belong[0],sum[belong[0]]);
	for (int i=0;i<n*m;i++){
		for (int j=head[i];j!=-1;j=edge[j].next){
			int v=edge[j].v;
			if (belong[i]!=belong[v])
				addedge2(belong[i],belong[v],sum[belong[v]]);
		}
	}
 SPFA();
}
void output(){
	printf("%d\n",ans);
}
int main(){
   // freopen("a.in","r",stdin);
	int T;
	scanf("%d",&T);
	while(T--){
		init();
		solve();
		output();
	}
	system("PAUSE");
}
Category: ACM | Tags: | Read Count: 1837

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com