数据不是很大,如果要转换为正常的那种建图方式的话,可以给点进行标号,用一个二维数组存这两条边相交的那个点的标号,方便处理。一定要注意不要同一个点使用不同的编号也不要不同的点使用同一个编号(这不是废话嘛)不展开。

想多说一下一种比较有意思的做法,就是把边看成点,把边权转化为点权。

这样的话,原本的最小环长就变成了一条路径上经过的所有点的点权之和啦。

大概,张这个样子吧:

边是没有权值的,它只表示连通性。

不过由于把边看成了点,所以处理有些特殊:

原本的$dis[i][j]$是指点$i$到点$j$所经过的边权之和的最小值,但边->点之后,就变成了点$i$到点$j$所经过的点权之和的最小值(含点$i$和点$j$),那么在转移的时候,原本的方程式$dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j])$就不能用,因为$dis[i][k]$和$dis[k][j]$都包含了点$k$的点权,所以要减去,应该写成这个样子:

$$dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]-pw[k]/*point-weight*/)$$

然后就用$floyd$求最小环就可以了

->$break$ $in$ $something$

简单说一下$floyd$求最小环,感觉就是做一遍$floyd$答案就是$dis[i][i]$。

但是不行啊,因为无法保证$dis[i][k]$和$dis[k][j]$表示的路是不一样的。

转移的时候是枚举$i$,$j$,$k$三重循环的嘛,就在每一次通过$k$转移之前(也就是现在的$dis[i][j]$是靠$1~k$作为中转站转移过来的)对最小环进行更新,因为$dis[i][j]$和$i->k->j$走的路肯定不一样(一个肯定没有经过$k$,一个肯定经过了$k$)

就可以啦。

(如果你会$floyd$的话,上面的应该都能看懂,不过不会的话可以百度一下,$floyd$不是很难)

->$end$

另外,有一个很坑的地方,是由于边->点造成的,如果边长成这个样子:

那把边搞成点就成了这个样子:

这是一个环,但是显然这个环是不符合题目要求的,因为题目要的是这种环:

特判一下就可以啦,由于$N$只有$100$,随便怎么搞都可以。

 /*
ID: Starry21
LANG: C++
TASK: fence6
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 105
#define INF 0x3f3f3f3f
int n,len[N]/*新图点权*/,ans=INF;
int dis[N][N]/*两点间最短距离(floyd)*/,s[N][N]/*直接距离(直接相连的)*/;
bool G[N][N]/*邻接矩阵*/,vis[N][N][N]/*判断三条边是否交于一点*/;
int tmp[N],ns[];//辅助输入,见程序
int main()
{
//freopen("fence6.in","r",stdin);
//freopen("fence6.out","w",stdout);
scanf("%d",&n);
for(int p=;p<=n;p++)
{
int id;scanf("%d",&id);
tmp[]=id;
scanf("%d %d %d",&len[id],&ns[],&ns[]);
for(int q=;q<=;q++)
{
for(int i=;i<=ns[q];i++)
{
int id2;scanf("%d",&id2);
G[id][id2]=G[id2][id]=;
tmp[i]=id2;//记录边交于一点的编号
for(int j=;j<i;j++)
for(int k=;k<j;k++)
vis[tmp[i]][tmp[j]][tmp[k]]=vis[tmp[i]][tmp[k]][tmp[j]]=vis[tmp[j]][tmp[i]][tmp[k]]=vis[tmp[j]][tmp[k]][tmp[i]]=vis[tmp[k]][tmp[i]][tmp[j]]=vis[tmp[k]][tmp[j]][tmp[i]]=;
}
}
}
memset(dis,0x3f,sizeof(dis));
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(G[i][j])
dis[i][j]=dis[j][i]=s[i][j]=s[j][i]=len[i]+len[j];
for(int k=;k<=n;k++)
{
for(int i=;i<=n;i++)
if(G[i][k])
for(int j=i+;j<=n;j++)
if(G[k][j]&&!vis[i][j][k])
ans=min(ans,dis[i][j]+s[i][k]+s[k][j]-len[i]-len[j]-len[k]);
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]-len[k]);
}
printf("%d\n",ans);
return ;
}

Code

USACO4.1 Fence Loops【最小环&边->点转化】的更多相关文章

  1. 洛谷P2738 [USACO4.1]篱笆回路Fence Loops

    P2738 [USACO4.1]篱笆回路Fence Loops 11通过 21提交 题目提供者该用户不存在 标签USACO 难度提高+/省选- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 ...

  2. 洛谷 P2738 [USACO4.1]篱笆回路Fence Loops

    P2738 [USACO4.1]篱笆回路Fence Loops 题目描述 农夫布朗的牧场上的篱笆已经失去控制了.它们分成了1~200英尺长的线段.只有在线段的端点处才能连接两个线段,有时给定的一个端点 ...

  3. USACO 4.1 Fence Loops(Floyd求最小环)

    Fence Loops The fences that surround Farmer Brown's collection of pastures have gotten out of contro ...

  4. USACO 4.1 Fence Loops

    Fence Loops The fences that surround Farmer Brown's collection of pastures have gotten out of contro ...

  5. [USACO4.1]篱笆回路Fence Loops

    题目:USACO Training 4.1(在官网上提交需加文件输入输出).洛谷P2738. 题目大意:给你一张图里的边集,让你求出这张图的最小环. 解题思路:求最小环很简单,用Floyd即可.最重要 ...

  6. 题解 P2738 【[USACO4.1]篱笆回路Fence Loops】

    这题是我期中测试的一题水题,然而英文题目太长了不想读...后面考完被同学提醒后20分钟切了(心塞) 切完看了波题解,发现貌似我的方法跟大家都不一样呢... 常规做法: \(Floyd\) 这个有三页的 ...

  7. USACO Section 4

    前言 好久没更新这个系列了,最近闲的无聊写一下.有两题搜索懒得写了. P2737 [USACO4.1]麦香牛块Beef McNuggets https://www.luogu.com.cn/probl ...

  8. usaco training 4.1.3 fence6 题解

    Fence Loops题解 The fences that surround Farmer Brown's collection of pastures have gotten out of cont ...

  9. USACO4.13Fence Loops(无向图最小环)

    最近脑子有点乱 老是不想清楚就啪啪的敲 敲完之后一看 咦..样例都过不去 仔细一想 这样不对啊 刚开始就写了一SPFA 最后发现边跟点的关系没处理好 删了..写dfs..还是没转化好 开始搜解题方法 ...

随机推荐

  1. CSS三角的写法(兼容IE6)

    目录 简介 优点 原理 1. 先创建一个div 2. 然后给div设定边框. 3. 给div的四个边框都设置不同的颜色 4. 把宽度和高度都变成0 5. 其余角为透明 6. 兼容IE6浏览器 造成这样 ...

  2. js 动态加载js 并执行

    function loadJS(url, success) { var domScript = document.createElement('script'); domScript.src = ur ...

  3. js 循环post

    var url_s=["h/a","h/b","h/c"]; function post_test(url,callback) { //请求 ...

  4. OpenCV笔记(6)(harris角点检测、背景建模)

    一.Harris角点 如上图所示,红色框AB都是平面,蓝色框CD都是边缘,而绿色框EF就是角点. 平面:框往X或Y抽移动,变化都很小. 边缘:框沿X或Y轴移动,其中一个变化很小,而另外一个变化比较大. ...

  5. JSONArray排序和倒转

    JSONArray排序 // JSONArray转list List<JSONObject> list = JSONArray.parseArray(ordersDataArray.toJ ...

  6. javascript中的原型和原型链(一)

    原型和原型链是 JS 中不可避免需要碰到的知识点,本文使用图片思维导图的形式缕一缕原型.原型链.实例.构造函数等等概念之间的关系. Constructor 构造函数 首先我们先写一个构造函数 Pers ...

  7. Java Optional orElse() 和 orElseGet() Optional.flatMap()和Optional.map()区别

    Java Optional 的 orElse() 和 orElseGet() 的区别 1. 接收的参数不同 orElse()方法以一个自定义类型的数据作为参数 public T orElse(T t) ...

  8. 【转】jQuery - 同时添加click和dblclick事件

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  9. 2019Java第十四周课程总结

    关于记事本代码上周已经写过了,这次把他粘过来了,如下: 记事本 package jishiben; import java.awt.event.ActionEvent; import java.awt ...

  10. Laravel 在构造方法中使用session