hdu:4360(spfa)求各种状态的最短路

来源:互联网 发布:matlab 矩阵符号运算 编辑:程序博客网 时间:2024/04/29 19:40

题意:每条边除了有边权以外,还有一个字母标记。标记可以是“LOVE”里面任意字符。

思路:这题是最短路的变形,用spfa需要记录一下到达这点时,有“LOVE”这四个字母结尾的四种状态,记录每一个状态的最短路,当最短路相等时选love最多的。这题找下一个点时需要两个字母是连在一块的

#include <iostream>#include <cstring>#include <vector>#include <cmath>#include <queue>#include <cstdio>#include <map>#define MAXN 10050#define MAXM 83520#define inf 9223372036854775807using namespace std;int head[MAXN];int cnt=0;int n,m;int get(char c){    if(c=='L')return 1;    if(c=='O')return 2;    if(c=='V')return 3;    if(c=='E')return 4;}struct Node{    int v,next;    int  w;    int ch;}edge[MAXN*20];void init(){    cnt=0;    memset(head,-1,sizeof(head));}void addedge(int u,int v,int w,char ch){    edge[cnt].v=v;    edge[cnt].ch=get(ch);    edge[cnt].w=w;    edge[cnt].next=head[u];    head[u]=cnt++;}struct NN{ int num; int falg;};__int64 dis[MAXN][6];int ans[MAXN][6];void spfa(){     int vis[MAXN][6];     memset(vis,0,sizeof(vis));     for(int i=1;i<=n;i++)      for(int j=1;j<=4;j++)        {           dis[i][j]=inf;           ans[i][j]=0;        }    memset(ans,0,sizeof(ans));    queue<NN>myqueue;    while(!myqueue.empty())myqueue.pop();    NN f;    f.falg=4;    f.num=1;    myqueue.push(f);    vis[1][4]=1;    dis[1][4]=0;    NN top;    while(!myqueue.empty())    {      top=myqueue.front();      myqueue.pop();      int u=top.num;      int ff=top.falg;      vis[u][ff]=0;      for(int i=head[u];i!=-1;i=edge[i].next)      {        int hh=edge[i].ch;        int v=edge[i].v;        int f=ff+1;        if(f>4)f=f%4;        if(dis[u][ff]+edge[i].w<dis[v][hh]&&f==hh)//距离较短则距离和“LOVE”个数都要更新        {            dis[v][hh]=dis[u][ff]+edge[i].w;            ans[v][hh]=ans[u][ff];            if(hh==4)            ans[v][4]++;            NN ne;            ne.num=v;            ne.falg=hh;            if(!vis[v][hh])            {                vis[v][hh]=1;                myqueue.push(ne);            }        }        else if(dis[v][hh]<inf&&dis[u][ff]+edge[i].w==dis[v][hh]&&f==hh)//距离相等则更新"LOVE"个数        {          if(ans[v][hh]<=ans[u][ff])          {              ans[v][hh]=ans[u][ff];              if(hh==4)              ans[v][hh]++;              if(!vis[v][hh])              {                vis[v][hh]=1;                NN ne;                ne.num=v;                ne.falg=hh;                myqueue.push(ne);              }          }        }      }      if(n==1&&ans[n][4]==0&&dis[n][4]==0)//只有一个点        dis[n][4]=inf;    }}int main(){    int u,v;    long long w;    int cas;    char ch[10];    int T=0;    scanf("%d",&cas);    while(cas--)    {      scanf("%d%d",&n,&m);      init();      for(int i=1;i<=m;i++)      {          scanf("%d %d %d %s",&u,&v,&w,ch);          addedge(u,v,w,ch[0]);//双向边          addedge(v,u,w,ch[0]);      }     spfa();     T++;     if(ans[n][4] == 0 || dis[n][4] >= inf)     printf("Case %d: Binbin you disappoint Sangsang again, damn it!\n", T);     else     printf("Case %d: Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n", T, dis[n][4], ans[n][4]);    }    return 0;}


原创粉丝点击