cf#33-B - String Problem-反向建图+最短路
来源:互联网 发布:南风知我意2傅云深 编辑:程序博客网 时间:2024/06/09 23:32
http://codeforces.com/problemset/problem/33/B
给出字符串s,t;n个字母替换关系 x,y,w
题意:求使得给出两个字符串完全一致的代价,【可根据一个有向图替换字符,并消耗相应代价】
字母表比较小,预处理所有方案,(i-j替换成一致的)最优方案是反向建图的最短路,n^2 * n^2 (可做到n^3,n=26就没必要了) ,然后O(n)遍历即可
反向建图的意思: 题目要求x,y的最短一致代价,即找出一条x联通y的最短路,但是由于给的边是有向的,可能最后的结果会是 x->k,y->k 即都替换成k,但是x,y并不直接联通,这样不方便用最短路,那么直接把边的方向反过来,枚举所有点作为起点, 求min(dis[x]+dis[y]) 得到的便是实际中最短的一条路了
代码中直接n*n*(n^2)了,实际直接n*n*n也可。。。
思路很快好了,傻逼错误犯了不少。。最短路的 break写成return,外循环变量i与内部重复了,更新路径判断条件写错了。
注意: 图的权重存在为0的,应该初始化为-1而不是0!
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <iostream>#include <queue>#include <map>#include <set>#include <vector>#include<stack>using namespace std; const double pi=acos(-1.0);const double eps=1e-6; const int inf=2147483647;char s1[100005];char tmp[100005];char s2[100005];int tm[30][30];int show[28];int check_dis[28][28];char check_ret[28][28];int get_dis(int st,int a,int b){int n=26;int i;int x=st; int dis[30];int vis[30];memset(dis,0,sizeof(dis));memset(vis,0,sizeof(vis));for (i=1;i<=n;i++){if (tm[x][i]!=-1)dis[i]=tm[x][i];elsedis[i]=inf;}vis[x]=1;dis[x]=0;for (int k=1;k<n;k++) //外循环变量i,与内循环变量重复,导致出现问题{int min_edge=inf;int minp=-1;for (i=1;i<=n;i++){if (!vis[i]&&dis[i]<min_edge){min_edge=dis[i];minp=i;}}if (minp==-1) break;//最短路写傻逼了。直接return -1;vis[minp]=1;for (i=1;i<=n;i++){if (!vis[i]&&tm[minp][i]!=-1&&dis[i]>min_edge+tm[minp][i])//*手误写错了dis[i]=min_edge+tm[minp][i];}}if (dis[a]==inf||dis[b]==inf) return -1;elsereturn dis[a]+dis[b];}int get_min_dis(char a,char b,char &tt){int x=a-'a'+1;int y=b-'a'+1;int i;int mini=-1;int ans=inf;for (i=1;i<=26;i++){if (!show[i]) continue;int ret=get_dis(i,x,y);if (ret==-1) continue;else{if (ret<ans) {mini=i;ans=ret;}}}if (ans==inf)return -1;tt=mini+'a'-1;return ans;}int main(){int i,j;int n;scanf("%s%s",s1,s2);cin>>n;getchar();char xx,yy;int x,y,w; memset(tm,-1,sizeof(tm));//权重存在为0,所以需要初始化为-1!!for (i=1;i<=n;i++){scanf("%c %c %d",&xx,&yy,&w);getchar();x=xx-'a'+1;y=yy-'a'+1;show[x]=1;show[y]=1;if (-1==tm[y][x])tm[y][x]=w;elseif (w<tm[y][x]) tm[y][x]=w;}int len1=strlen(s1);int len2=strlen(s2);if (len1!=len2){printf("-1\n"); return 0;}for (i=1;i<=26;i++){for (j=i+1;j<=26;j++){char tt;int ret=get_min_dis(i+'a'-1,j+'a'-1,tt);check_dis[i][j]=check_dis[j][i]=ret;check_ret[i][j]=check_ret[j][i]=tt;} }strcpy(tmp,s1);int ans=0;for (i=0;i<len1;i++){if (s1[i]==s2[i]) continue;char tt=check_ret[s1[i]-'a'+1][s2[i]-'a'+1];int ret=check_dis[s1[i]-'a'+1][s2[i]-'a'+1];if (ret==-1){printf("-1\n"); return 0;}tmp[i]=tt; ans+=ret;}printf("%d\n%s\n",ans,tmp);return 0;}
0 0
- cf#33-B - String Problem-反向建图+最短路
- CF 33B String Problem
- CF 543B 图,最短路
- cf 689 B(最短路)
- CF 715B 最短路
- Proxy 最短路 反向建图
- CF-30 D - King's Problem?(枚举+最短路)
- CF 173B Chamber of Secrets 最短路
- cf B. Obsession with Robots 判断最短路?
- CF 449B - Jzzhu and Cities(最短路)
- CF 505B Mr. Kitayuta's Colorful Graph(最短路)
- poj1511 spfa最短路+手写邻接表+反向建图
- POJ Silver Cow Party (最短路+反向建图)
- poj1062昂贵的聘礼【最短路反向建图】
- Choose the best route 【最短路】+【反向建图】
- cf 602 C(最短路)
- CF 337B - Routine Problem
- 最短路 -B
- 用數組求平均數並列出大於平均數的數
- php如果执行一个死循环及后台自动执行
- Window下的dos环境下编译运行下运行c程序
- 用函數求任意一個數到另一個數中所有數之和(包括本身)
- 交换分区管理
- cf#33-B - String Problem-反向建图+最短路
- 【2016/1】 Unix IPC 信号 共享内存 消息队列
- thinkphp无法识别数据表名大小写问题
- 文章标题
- hihoCoder 1069 最近公共祖先 在线算法
- 编辑距离算法(dp)
- 查找某個數字是否在數組中(數組複習)
- Java Web项目相对路径
- 卫星地图(貌似USACO)