你是一个翻译官,翻啊翻译官。
给定n,n个目标语言,
求你把英语翻译成其他语种的最小花费,
并且要求距离英语最近。。(经过一个第三方翻译,就是两层),直接翻译就是一层。
由于第二个条件的限制,所以不是最短路啦。
但是在比赛的时候,我觉得可以先用dinic跑一下层数,然后再跑一下spfa,在判断是否为松弛操作的时候,加一个限制条件,那就是层数必须小。
但是很可悲的wa了。应该是有数据卡。
第九组数据过不了
因为这样写本来就得到的是有限制条件的最短路,但是并不能证明最终要输出的路径是一个最短路,
附上错误代码,原谅我这个逗逼–
wa的代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=6000;
struct Node
{ char a[maxn];
int num;
}node[maxn*2];
struct Tree
{ int from,to,cost,next;
}tree[maxn*2];
int n,m;
int head[maxn];
int len;
bool vis[maxn];
int dis[maxn];
int ranks[maxn];
int pre[maxn];
int check(char x[])
{ for(int i=0;i<=n;i++)
{ if(strcmp(node[i].a,x)==0)
{
//printf("%s %s\n",node[i].a,x);
return i;
}
//return i;
}
return -1;
}
void add(int u,int v,int value)
{ tree[len].from=u;
tree[len].to=v;
tree[len].cost=value;
tree[len].next=head[u];
head[u]=len++;
}
void init()
{ memset(head,-1,sizeof(head));
len=0;
}
void spfa()
{
memset(dis,0x3f,sizeof(dis));
memset(pre,-1,sizeof(pre));
memset(vis,0,sizeof(vis));
dis[0]=0;
vis[0]=true;
queue<int>q;
q.push(0);
while(!q.empty())
{ int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u];i!=-1;i=tree[i].next)
{ int s=tree[i].to;
int len=tree[i].cost;
if(dis[s]>dis[u]+len&&ranks[s]>=ranks[u]+1)//there
{ dis[s]=len+dis[u];
pre[s]=u;
if(!vis[s])
{q.push(s);
vis[s]=1;}
}
}
}
// for(int i=1;i<=m;i++)
//cout<<dis[i]<<endl;
return ;
}
int ceshi()
{ for(int i=0;i<=n;i++)
if(dis[i]==0x3f3f3f3f)
return -1;
int sum=0;
/*for(int i=0;i<=n;i++)
for(int j=head[i];j!=-1;j=tree[j].next)
{ if(dis[i]+tree[j].cost==dis[tree[j].to])
{ //printf("%d %d %d\n",i,tree[j].to,tree[j].cost);
sum+=tree[j].cost;}*/
/*for(int i=1;i<=n;i++)
sum+=dis[i];*/
for(int i=1;i<=n;i++)
{ if(pre[i]!=-1)
{ int s=pre[i];
for(int j=head[s];j!=-1;j=tree[j].next)
{ int l=tree[j].to;
if(l==i)
{sum+=tree[j].cost;
break;
}
}
}
}
return sum;
}
void bfs()
{
queue<int>q;
memset(ranks,-1,sizeof(ranks));
ranks[0]=1;
q.push(0);
while(!q.empty())
{ int u=q.front();
q.pop();
for(int i=head[u];i!=-1;i=tree[i].next)
{ int e=tree[i].to;
if(ranks[e]==-1)
{ ranks[e]=ranks[u]+1;
q.push(e);
}
}
}
return ;
}
int main()
{
while(scanf("%d%d",&n,&m)!=-1)
{
char x[maxn];
char y[maxn];
strcpy(node[0].a,"English");
node[0].num=0;
//getchar();
//printf("%s************\n",node[0].a);
for(int i=1;i<=n;i++)
{ cin>>x;
strcpy(node[i].a,x);
node[i].num=i;
}
//printf("%s\n",node[1].a);
init();
int num=0;
for(int i=1;i<=m;i++)
{ cin>>x>>y>>num;
//printf("%s %s\n",x,y);
int x1=check(x);
//printf("****%d\n",x1);
int y1=check(y);
//printf("%d %d\n",x1,y1);
add(x1,y1,num);
add(y1,x1,num);
}
/*for(int i=0;i<=n;i++)
for(int j=head[i];j!=-1;j=tree[j].next)
{ printf("%d %d %d\n",i,tree[j].to,tree[j].cost);
}*/
bfs();
//for(int i=0;i<=n;i++)
//printf("%d \n",ranks[i]);
spfa();
int l=ceshi();
if(l!=-1)
printf("%d\n",l);
else
printf("Impossible\n");
return 0;}
}
2 正确的打开方式
用优先队列轻松搞定。妈蛋就是一个stl的题。。
我算是明白了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <map>
#include <string>
#include <cstring>
const int maxn=2000;
using namespace std;
struct Node
{ int to,c,w;
Node(int a,int b,int m){to=a;c=b;w=m;}
};//node[maxn];
int len;
bool operator<(const Node &a,const Node &b)
{ if(a.c==b.c)
return a.w>b.w;
return a.c>b.c;
}
bool vis[maxn];
priority_queue<Node>que;
vector<Node>G[maxn];
map<string,int>p;
int main()
{ int n,m;
string t,s;
int cost;
scanf("%d%d",&n,&m);
p["English"]=0;
for(int i=1;i<=n;i++)
{cin>>t;
p[t]=i;}
for(int i=1;i<=m;i++)
{ cin>>t>>s>>cost;
int x=p[t];
int y=p[s];
G[x].push_back(Node(y,0,cost));
G[y].push_back(Node(x,0,cost));
//printf("%d %d\n",x,y);
}
memset(vis,false,sizeof(vis));
que.push(Node(0,0,0));
//vis[0]=true;
int sum=0;
while(!que.empty())
{ Node u=que.top();
que.pop();
//printf(" %d **\n",u.to);
if(vis[u.to]) continue;
//if(!vis[u.to])
//printf("%d\n",u.w);
sum+=u.w;
vis[u.to]=true;
for(int i=0;i<G[u.to].size();i++)
{ int s=G[u.to][i].to;
//int c=G[u.to][i].c;
int w=G[u.to][i].w;
que.push(Node(s,u.c+1,w));
}
//vis[u.to]=true;
}
for(int i=1;i<=n;i++)
{ if(!vis[i])
{printf("Impossible\n");
return 0;}
}
printf("%d\n",sum);
return 0;
}