又到了一年一度的明明生日了,明明想要买 B B B 样东西,巧的是,这 B B B 样东西价格都是 A A A 元。
但是,商店老板说最近有促销活动,也就是:
如果你买了第 I I I 样东西,再买第 J J J 样,那么就可以只花 K I , J K_{I,J} KI,J 元,更巧的是, K I , J K_{I,J} KI,J 竟然等于 K J , I K_{J,I} KJ,I。
现在明明想知道,他最少要花多少钱。
第一行两个整数, A , B A,B A,B。
接下来 B B B 行,每行 B B B 个数,第 I I I 行第 J J J 个为 K I , J K_{I,J} KI,J。
我们保证 K I , J = K J , I K_{I,J}=K_{J,I} KI,J=KJ,I 并且 K I , I = 0 K_{I,I}=0 KI,I=0。
特别的,如果 K I , J = 0 K_{I,J}=0 KI,J=0,那么表示这两样东西之间不会导致优惠。
一个整数,为最小要花的钱数。
1 1
0
1
3 3
0 2 4
2 0 2
4 2 0
7
样例解释 2 2 2。
先买第 2 2 2 样东西,花费 3 3 3 元,接下来因为优惠,买 1 , 3 1,3 1,3 样都只要 2 2 2 元,共 7 7 7 元。
(同时满足多个“优惠”的时候,聪明的明明当然不会选择用 4 4 4 元买剩下那件,而选择用 2 2 2 元。)
数据规模
对于 30 % 30\% 30% 的数据, 1 ≤ B ≤ 10 1\le B\le 10 1≤B≤10。
对于 100 % 100\% 100% 的数据, 1 ≤ B ≤ 500 , 0 ≤ A , K I , J ≤ 1000 1\le B\le500,0\le A,K_{I,J}\le1000 1≤B≤500,0≤A,KI,J≤1000。
2018.7.25新添数据一组
#include
using namespace std;
#define FOR(i,n,s) for(int i=(s);i<=(n);i++)
const int MAX=1e6+5;
int a,b;
int cntedge=1,cntpoint=1,sum=0,tot=0;//sum记录边权和,cntedge记录连了多少条边,cntpoint记录遍历到那个结点,tot记录总边数
struct node
{
int u,v,w;
}edges[MAX];//存边的结构体
//
int f[MAX];//并查集的维护数组,表示根结点
int find(int x)
{
if(x==f[x]) return x;
else return f[x]=find(f[x]);
}//并查集查找函数:查找x的根节点
void init()
{
FOR(i,b,1) f[i]=i;
}//并查集初始化函数:将每个结点的根结点先默认为它自己
void merge(int u,int v)
{
f[find(u)]=find(v);
}//并查集合并函数:将u和v的根结点合并
//
//并查集
//
void addedge(int u,int v,int w)
{
tot++;
edges[tot].u=u;
edges[tot].v=v;
edges[tot].w=w;
}//加边
bool cmp(node a,node b)
{
return a.w<b.w;
}//按照边权从小到大排序
void kruskal()
{
sort(edges+1,edges+1+tot,cmp);//Kruskal最小生成树的思想,将边权按照从小到大排序
while(cntedge<=tot&&cntpoint<=b)
{
if(find(edges[cntedge].u)!=find(edges[cntedge].v))//如果个结点之间没有回路,则可以合并
{
merge(edges[cntedge].u,edges[cntedge].v);//合并
sum+=edges[cntedge].w;//更新最小边权和
cntpoint++;
}
cntedge++;
}
}
//
//最小生成树
int main()
{
cin>>a>>b;
init();
for (int i=1;i<=b;i++)
for (int j=1;j<=b;j++)
{
int x;
cin>>x;
if(i>j || x==0) continue;
addedge(i,j,x);
}
for(int i=1;i<=b;i++)
addedge(0,i,a);//建立一个0结点(虚拟结点),表示所有的物品都能买到
kruskal();
cout<<sum;
return 0;
}
与上一个题类似,单源最短路,用kruskal解决,大体模版于上个题类似,但是需要建立一个0结点,表示所有的物品都能买得到