POJ 3592 Instantaneous Transference 强连通缩点+dp最长路
2017-08-18 20:28
369 查看
题目链接:
http://poj.org/problem?id=3592题意
在一个n*m的方格中,方格可以填三种类型的字符,1.数字
2.’*’
3.’#’
数字代表他到达这儿所能获得的价值,*表示这点为传输机,走到这儿可以选择传送与它绑定的某个点,#代表墙壁,不能走到这儿。一个人从左上角走到右下角,在每个点只能往下或往右,在传输机位置处,可以选择传送或不传送,每个点的价值只能获得一次,问这个人能获得的最大价值。
思路
按照题中描叙的方式建图,缩点后形成dag。然后求dag上的最长路。容易错的地方:起点(左上角)所在的连通分量的dp值为最终答案。这道题真的要细心,太容易出错了。
#include<cstdio> #include<queue> #include<iostream> #include<vector> #include<map> #include<cstring> #include<string> #include<set> #include<stack&g fb44 t; #include<algorithm> #define cle(a) memset(a,0,sizeof(a)) #define inf(a) memset(a,0x3f,sizeof(a)) #define ll long long #define Rep(i,a,n) for(int i=a;i<=n;i++) using namespace std; const int INF = ( 2e9 ) + 2; const ll maxn = 1700; vector<int> g[maxn],dag[maxn]; char mp[50][50]; int time,num; int dfn[maxn],low[maxn],instack[maxn],scc[maxn],w[maxn],w2[maxn]; int dp[maxn]; stack<int> s; void tarjan(int u) { dfn[u]=low[u]=++time; instack[u]=1; s.push(u); for(int i=0,L=g[u].size();i<L;i++) { int v=g[u][i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(instack[v]) low[u]=min(low[u],low[v]); } if(dfn[u]==low[u]) { num++; int x; do { x=s.top();s.pop(); w2[num]+=w[x]; instack[x]=0; scc[x]=num; }while(x!=u); } } int find(int u) { if(dp[u]!=-INF)return dp[u]; dp[u]=w2[u]; for(int i=0;i<dag[u].size();i++) { int v=dag[u][i]; dp[u]=max(dp[u],w2[u]+find(v)); } return dp[u]; } int main() { int t; // freopen("in.txt","r",stdin); scanf("%d",&t); while(t--) { int n,m; time=num=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(w,0,sizeof(w)); memset(w2,0,sizeof(w2)); memset(scc,-1,sizeof(scc)); while(!s.empty())s.pop(); scanf("%d%d",&n,&m); for(int i=0;i<=(n*m);i++) { g[i].clear(); dag[i].clear(); } for(int i=0;i<n;i++) scanf("%s",mp[i]); int cnt=0; for(int i=0;i<n;i++) for(int j=0;j<m;j++) { int t=i*m+j; if(mp[i][j]>='0'&&mp[i][j]<='9') w[t]=mp[i][j]-'0'; else if(mp[i][j]=='#') dfn[t]=1; if(i>0&&mp[i-1][j]!='#'&&mp[i][j]!='#') { int l=m*(i-1)+j; g[l].push_back(t); } if(j>0&&mp[i][j-1]!='#'&&mp[i][j]!='#') { int l=m*i+j-1; g[l].push_back(t); } if(mp[i][j]=='*') { int x,y; scanf("%d%d",&x,&y); int c=x*m+y; if(mp[x][y]!='#') g[t].push_back(c); } } for(int i=0;i<(n*m);i++) if(!dfn[i])tarjan(i); for(int i=0;i<n*m;i++) { for(int j=0,L=g[i].size();j<L;j++) if(scc[i]!=scc[g[i][j]]) { dag[scc[i]].push_back(scc[g[i][j]]); } } int ans=-INF; for(int i=0;i<=num;i++)dp[i]=-INF; for(int i=1;i<=num;i++) find(i); ans=dp[scc[0]]; printf("%d\n",ans); } }
另外还写了个数据生成的程序,对拍时发现网上一些ac代码竟然有些数据过不了
#include<cstdio> #include<queue> #include<iostream> #include<vector> #include<map> #include<time.h> #include<stdlib.h> #include<cstring> #include<string> #include<set> #include<stack> #include<algorithm> #define cle(a) memset(a,0,sizeof(a)) #define inf(a) memset(a,0x3f,sizeof(a)) #define ll long long #define Rep(i,a,n) for(int i=a;i<=n;i++) using namespace std; const int INF = ( 2e9 ) + 2; int main() { srand(time(NULL)); freopen("in.txt","w",stdout); int t=rand()%20; printf("%d\n",t); while(t--) { int n,m; n=rand()%10+1; m=rand()%10+1; printf("%d %d\n",n,m); int cnt=0; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { int f=rand()%7; int t=rand()%10; if(f==0) { printf("%c",'*'); cnt++; } else if(f==1) printf("%c",'#'); else printf("%c",t+'0'); } printf("\n"); } for(int i=0; i<cnt; i++) { int x,y; x=rand()%n; y=rand()%m; printf("%d %d\n",x,y); } } }
相关文章推荐
- poj 3592 Instantaneous Transference 强连通缩点+在DAG上dp求最长路
- POJ 3592 Instantaneous Transference(建图强连通+单源最长路)
- poj 3160 (强连通缩点&简单dp)
- POJ 3592 Instantaneous Transference(强连通+DP)
- poj 3160 Father Christmas flymouse(强连通缩点+最长路)
- Light OJ 1406 Assassin`s Creed 状态压缩DP+强连通缩点+最小路径覆盖
- POJ (简单 dp ,最长升序子串)
- poj 2127 dp(最长公共递增子序列)
- POJ 1631 Bridging signals DP(最长上升子序列)
- 【强连通缩点+最短路】 POJ 3114 Countries in War
- POJ_2533 Longest Ordered Subsequence【DP】【最长上升子序列】
- POJ (dp最长上升子序列问题)
- POJ 2762判断单联通(强连通缩点+拓扑排序)
- poj1236强连通缩点
- poj 1236 Network of Schools 【SCC + 缩点】【最少连接几个点可以直接或间接连接所有点 + 增加最少的边使图强连通】
- [算法] poj 3903 最长上升子序列 dp vs (二分 nlogn)
- (复习)poj 1952 最长下降子序列—— dp+方案个数
- POJ 1952 LITTLE SHOP OF FLOWERS(DP动归,最长递减子序列)
- POJ3160 Father Christmas flymouse[强连通分量 缩点 DP]
- poj1236强连通缩点