题目连接

  • 题意:

    给定一个无向图,每一个边有两个属性。长度和一个字母‘L',’O',‘V’。‘E'中的一个。从1点開始到达n点,每次必须依照L -> O -> V -> E -> ... -> E的顺序。到达终点时候必须经过E边
  • 分析:

    对于这样的对边的限制,比較简单的方法是将一个点拆成若干个点。由于经过’L'到达点p的状态和经过‘O'到达点p的状态时不一样的,第一个之后仅仅能经过’O'边。而第二个仅仅能经过‘V'边,所以经过不同的边到达同一个点的时候相应的状态应该分开。也就是将点拆分成四个点。分别表示经过四种边到达p点。

  • 注意:

    图能够有自环。也能够仅仅有一个点

    路径必须至少有一个LOVE

    路径长度尽可能小,长度若相等,那么LOVE的数量尽可能多
Dijkstra方法:(一个点的时候直接特判。避免不必要的麻烦)
const LL INF = 1e18;
const int MAXV = 10000; struct Edge
{
LL from, to, dist;
}; struct HeapNode
{
LL d, u, num;
bool operator < (const HeapNode& rhs) const
{
return d > rhs.d;
}
}; struct Dijkstra
{
int n; //n:点数 m:暂时变量
vector<Edge> edges; //存储全部的边
vector<int> G[MAXV];//每一个点的全部相邻边序号
bool done[MAXV]; // 是否已永久标号
LL d[MAXV]; // s起点到各个点的距离
LL num[MAXV]; void init(int n)
{
this->n = n;
for(int i = 0; i < n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int dist)
{
G[from].push_back(edges.size());
edges.push_back((Edge) { from, to, dist });
} void dijkstra(int s)
{
priority_queue<HeapNode> Q;
for(int i = 0; i < n; i++) d[i] = INF;
CLR(num, 0);
d[s] = 0;
memset(done, 0, sizeof(done));
Q.push((HeapNode) { 0, s, 0 });
while(!Q.empty())
{
HeapNode x = Q.top();
Q.pop();
int u = x.u;
if(done[u]) continue;
done[u] = true;
for(int i = 0; i < G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
if (d[e.to] == d[u] + e.dist)
num[e.to] = max(num[e.to], num[x.u] + 1);
if(d[e.to] > d[u] + e.dist)
{
d[e.to] = d[u] + e.dist;
num[e.to] = num[x.u] + 1;
Q.push((HeapNode) { d[e.to], e.to, num[e.to] });
}
}
}
}
} dij; LL chk[4]; int main()
{
int T;
RI(T);
FE(kase, 1, T)
{
REP(i, 4) chk[i] = INF;
int n, m, u, v, d, op;
char type;
RII(n, m);
dij.init(n << 2);
REP(i, m)
{
scanf("%d%d%d %c", &u, &v, &d, &type);
u--; v--;
if (type == 'L') op = 0;
else if (type == 'O') op = 1;
else if (type == 'V') op = 2;
else op = 3;
chk[op] = min(chk[op], (LL)d);
dij.AddEdge(u + (op + 3) % 4 * n, v + op * n, d);
dij.AddEdge(v + (op + 3) % 4 * n, u + op * n, d);
}
printf("Case %d: ", kase);
if (n == 1)
{
REP(i, 4)
if (chk[i] == INF)
{
puts("Binbin you disappoint Sangsang again, damn it!");
goto end;
}
printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n"
, chk[0] + chk[1] + chk[2] + chk[3], 1);
end:;
}
else
{
dij.dijkstra(3 * n);
if (dij.d[4 * n - 1] == INF)
puts("Binbin you disappoint Sangsang again, damn it!");
else
{
printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %I64d LOVE strings at last.\n"
, dij.d[4 * n - 1], dij.num[4 * n - 1] / 4);
}
}
}
return 0;
}




spfa方法:(一个点也是特判,加点方式与Dijkstra同样)
const LL INF = 1e18;
const int MAXV = 10000; struct Edge
{
int from, to, dist;
}; struct SPFA
{
int n;
LL d[MAXV];
int num[MAXV];
vector<Edge> edges;
vector<int> G[MAXV];
bool inq[MAXV];
void init(int n)
{
this->n = n;
edges.clear();
REP(i, n)
G[i].clear();
}
void AddEdge(int from, int to, int dist)
{
G[from].push_back(edges.size());
edges.push_back((Edge) {from, to, dist});
}
void spfa(int s)
{
queue<int> q;
CLR(inq, false);
CLR(num, 0);
REP(i, n) d[i] = INF;
d[s] = 0;
q.push(s); inq[s] = true;
while (!q.empty())
{
int u = q.front();
q.pop(); inq[u] = false;
REP(i, G[u].size())
{
Edge& e = edges[G[u][i]];
if (d[e.to] == d[u] + e.dist && num[u] + 1 > num[e.to])
{
num[e.to] = num[u] + 1;
if (!inq[e.to])
{
q.push(e.to);
inq[e.to] = true;
}
}
if(d[e.to] > d[u] + e.dist)
{
d[e.to] = d[u] + e.dist;
num[e.to] = num[u] + 1;
if (!inq[e.to])
{
q.push(e.to);
inq[e.to] = true;
}
}
}
}
}
} spfa; LL chk[4]; int main()
{
int T;
RI(T);
FE(kase, 1, T)
{
REP(i, 4) chk[i] = INF;
int n, m, u, v, d, op;
char type;
RII(n, m);
spfa.init(n << 2);
REP(i, m)
{
scanf("%d%d%d %c", &u, &v, &d, &type);
u--; v--;
if (type == 'L') op = 0;
else if (type == 'O') op = 1;
else if (type == 'V') op = 2;
else op = 3;
chk[op] = min(chk[op], (LL)d);
spfa.AddEdge(u + (op + 3) % 4 * n, v + op * n, d);
spfa.AddEdge(v + (op + 3) % 4 * n, u + op * n, d);
}
printf("Case %d: ", kase);
if (n == 1)
{
REP(i, 4)
if (chk[i] == INF)
{
puts("Binbin you disappoint Sangsang again, damn it!");
goto end;
}
printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n"
, chk[0] + chk[1] + chk[2] + chk[3], 1);
end:;
}
else
{
spfa.spfa(3 * n);
if (spfa.d[4 * n - 1] == INF)
puts("Binbin you disappoint Sangsang again, damn it!");
else
{
printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n"
, spfa.d[4 * n - 1], spfa.num[4 * n - 1] / 4);
}
}
}
return 0;
}




顺便弄一些自己的測试数据。方便查错。

4 4

1 2 1 L

2 1 1 O

1 3 1 V

3 4 1 E

ans:4, 1





4 4

1 2 1 L

2 3 1 O

3 4 1 V

4 1 1 E

ans:no





12  12

1 5 10 L

5 6 10 O

6 7 10 V

7 12 10 E

1 2 1 L

2 3 1 O

3 4 1 V

4 8 1 E

8 9 1 L

9 10 1 O

10 11 1 V

11 12 33 E

ans:40, 2





12  12

1 5 10 L

5 6 10 O

6 7 10 V

7 12 10 E

1 2 1 L

2 3 1 O

3 4 1 V

4 8 1 E

8 9 1 L

9 10 1 O

10 11 1 V

11 12 34 E

ans:40, 1





1 4

1 1 1 L

1 1 1 O

1 1 1 V

1 1 1 E

ans:4, 1





2 8

1 1 2 L

1 1 1 O

1 1 1 V

1 1 1 E

1 2 3 L

2 1 1 O

1 2 1 V

2 1 1 E

ans:5, 1





1 3

1 1 1 L

1 1 1 O

1 1 1 E

ans:no





11 11

1 2 1 L

2 3 1 O

3 4 348 V

4 11 1000 E

1 5 50 L

5 6 50 O

6 7 50 V

7 8 50 E

8 9 50 L

9 10 50 O

10 4 50 V

ans:1350 2

As long as Binbin loves Sangsang的更多相关文章

  1. HDU 4360 As long as Binbin loves Sangsang spfa

    题意: 给定n个点m条边的无向图 每次必须沿着LOVE走,到终点时必须是完整的LOVE,且至少走出一个LOVE, 问这样情况下最短路是多少,在一样短情况下最多的LOVE个数是多少. 有自环. #inc ...

  2. 2012 Multi-University #7

    最短路+拆点 A As long as Binbin loves Sangsang 题意:从1走到n,每次都是LOVE,问到n时路径是连续多个"LOVE"的最短距离.秀恩爱不想吐槽. 分析:在普通的最 ...

  3. 【转】最短路&差分约束题集

    转自:http://blog.csdn.net/shahdza/article/details/7779273 最短路 [HDU] 1548 A strange lift基础最短路(或bfs)★254 ...

  4. 8-12-COMPETITION

    链接:最短路 A.HDU 2544    最短路 算是最基础的题目了吧.............我采用的是Dijkstra算法....... 代码: #include <iostream> ...

  5. 2012 Multi-University Training Contest 7

    2012 Multi-University Training Contest 7 A.As long as Binbin loves Sangsang B.Dead or alive C.Dragon ...

  6. 转载 - 最短路&差分约束题集

    出处:http://blog.csdn.net/shahdza/article/details/7779273 最短路 [HDU] 1548    A strange lift基础最短路(或bfs)★ ...

  7. Microsoft Loves Linux

    微软新任CEO纳德拉提出的“Microsoft Loves Linux”,并且微软宣布.NET框架的开源,近期Microsoft不但宣布了Linux平台的SQL Server,还宣布了Microsof ...

  8. 5806 NanoApe Loves Sequence Ⅱ(尺取法)

    传送门 NanoApe Loves Sequence Ⅱ Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K ...

  9. 5805 NanoApe Loves Sequence(想法题)

    传送门 NanoApe Loves Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/131072 K ( ...

随机推荐

  1. fzu 1909 An Equation(水题)

    题目链接:fzu 1909 An Equation 典型的签到题. #include <stdio.h> #include <string.h> bool judge(int ...

  2. 自绘XP风格菜单

    这是以前写的代码,自绘XP风格的菜单,硬盘坏了后以为没了,最后写的一个软件要自定义风格,“翻箱倒柜”的终于在我可爱的古董机^_^上找到了一个应用的例子.还是把它放到Blog上来,即可共享又可作为备用 ...

  3. 用DELPHI的RTTI实现对象的XML持久化

    去年我花了很多时间尝试用DELPHI进行基于XML的WEB应用开发.起初的设想是很美好的,但结果做出来的东西很简陋.一部分原因就在于XML到Object之间的数据绑定实现太麻烦(另一部分是因为对XSL ...

  4. CSipSimple最新版本号

    要使用CSipSimple有两种方法:第一种是不编译jni,另外一种是编译jni. 这里介绍的是第一种:不编译jni. 首先,用SVNclient检出CSipSimple源代码:svn checkou ...

  5. C语言深度解剖读书笔记(6.函数的核心)

    对于本节的函数内容其实就没什么难点了,但是对于函数这节又涉及到了顺序点的问题,我觉得可以还是忽略吧. 本节知识点: 1.函数中的顺序点:f(k,k++);  这样的问题大多跟编译器有关,不要去刻意追求 ...

  6. Android 百度地图 SDK v3.0.0 (三) 加入覆盖Marker与InfoWindow使用

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/37737213 上篇博客已经实现了地图的定位以及结合了方向传感器用户路痴定位方向, ...

  7. 谁说程序员都是苦逼的——看看兄弟连上海S2班的点点滴滴

    时间过的很快,上海校区第三期马上临近开班,第一期的学员也结束了自己第一个项目.         今天,2013.05.08日,我亲自参加了S01的第一个项目答辩,也为你们记录下了这样那样的一些时刻.其 ...

  8. 移动App-UI配制篇

    杂志app-UI配制篇 背景 现在公司有需求是关于杂志app,里面每个页面可能有不同的展现方式,不同的内容,不同的操作方式.那么这里就有一个需求就是根据用户定制这些不同的展现方式,不同的内容,不同的操 ...

  9. (Android) Download Images by AsyncTask API

    1. Check network status AndroidManifest.xml <uses-sdk> ... </> <uses-permission andro ...

  10. 苹果手表的真实触感信息(Real Touch Messaging)

    苹果手表凭借其炫酷的设计和界面,无疑已成为一个新的科技焦点,也是苹果在可穿戴领域的重头戏. Apple Watch 有一个非常吸引人的特性:Real Touch Messaging,也就是真实触感消息 ...