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

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

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

大概,张这个样子吧:

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

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

原本的$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. package+explorer不显示项目的问题

    昨天遇到了这个问题,百度了一下,怎么搞的都有,但是感觉都不理想,晚上的时候才在网上又发现这个方法,今天试了一下,效果还不错,分享一下. 点击 Window ---> Close All Pers ...

  2. Notepad++设置快捷键及外部命令

    <NotepadPlus> <InternalCommands> <Shortcut id="41020" Ctrl="no" A ...

  3. qt5---布局

    QHBoxLayout  水平布局: Header:   #include <QHBoxLayout> qmake:  QT += widgets Inherits:QBoxLayout ...

  4. vs code 写VUE代码 注释 html出现 //

    装个插件 "Vuter" 解决

  5. Nowcoder Sum of Maximum ( 容斥原理 && 拉格朗日插值法 )

    题目链接 题意 : 分析 : 分析就直接参考这个链接吧 ==> Click here 大体的思路就是 求和顺序不影响结果.故转化一下思路枚举每个最大值对答案的贡献最后累加就是结果 期间计数的过程 ...

  6. 1003: [ZJOI2006]物流运输

    就我一开始写状压的吗? 调不过 后来发现(直接搜索)直接最短路就行了-- \(f[i]\)表示前\(i\)天最少需要多少 \(f[i] = min(f[j] + dis(j + 1, i))\) 然后 ...

  7. CF1213D Equalizing by Division

    easy version hard version 问题分析 直接从hard version入手.不难发现从一个数\(x\)能得到的数个数是\(O(\log x)\)的.这样总共有\(O(n\log ...

  8. Android_(控件)动态添加或删除Spinner下拉菜单

    使用ArrayList动态数组的依赖性实现动态增减Spinner下拉菜单选项功能. 设置一个EditText输入框,当用户输入了文字并单击[添加]按钮的同时,就会将输入的值添加Spinner至下拉菜单 ...

  9. linux下安装R第三方包forecast

    ERROR: [root@localhost soft]# R CMD INSTALL curl_3.1.tar.gz WARNING: ignoring environment value of R ...

  10. 【每日一包0009】group-array

    [github地址:https://github.com/ABCDdouyae...] group-array 对数组里面的多项按照指定的key进行整合 用法:group-array(arr, key ...