>Description
一个城市至多只能有一间医院,同时,两个相邻的城市也只能有一间医院。注意城市i与城市j相邻当且仅当G中存在一条有向边<i,j>或<j,i>。其他城市没有医院的人:
S[i] = ( 离城市i最近的医院到城市i所经过的边数 / 3 ) * U
你要注意你的方案必须能让医院覆盖到所有的城市,即每个城市都至少有一个医院能出发到达。
>Input
输入第一行为两个整数N和M,分别表示城市数与边的数量。1<=N<=100,0<=M<=10000。
接下来M行,每行两个整数X和Y,1<=X,Y<=N,X≠Y,表示存在一条X到Y的有向边。
最后一行为一个整数U,为定义不满意度值中使用到的那个常数。
>Output
输出包含三行,第一行为你找到的最小的不满意度值之和,第二行为你的方案建立的医院数量H,第三行有H个整数,为建立医院所在的城市,按城市编号由小到大排序。这样的方案可能不唯一,在保证不满意度值之和最小的情况下,输出任意一种均可。
>Sample Input
4 3
2 1
4 3
3 2
10
>Sample Output
0
2
2 4
>解题思路
T_T水代码,bug值得你拥有。
巨大模拟。
把入度为0的直接设为医院,然后算路径,路径大于等于3的也直接设为医院。
>水代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct ooo
{
int to,next;
}a[10005]; //邻接表a储存每一个点可以到达的点(to)
struct oo
{
int from,next;
}b[10005]; //邻接表b储存每一个点可以从那一些点过来(from)
int x,y,n,m,h[105],hh[105],u;
int lhq[105],c[105],t;
bool yd[105];
int main()
{
memset(c,0x7f,sizeof(c));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
lhq[y]++; //lhq存入度
a[i]=(ooo){y,h[x]}; h[x]=i;
b[i]=(oo){x,hh[y]}; hh[y]=i; //邻接表们
}
scanf("%d",&u);
printf("0\n"); //不管怎样都一定是0
for(int i=1;i<=n;i++)
if(lhq[i]==0) //入度为0的设为医院
{
yd[i]=1; t++; c[i]=0; //依次:把i标记为医院,医院数t++,i的路径为0
for(int j=h[i];j;j=a[j].next) //处理i所连接的点
{
c[a[j].to]=1; //路径为1
if(yd[a[j].to]) t--;
yd[a[j].to]=0; //如果它(连接的点)以前为医院就不设它为医院
}
}
for(int i=1;i<=n;i++)
{
if(c[i]==c[0]) //如果当前点没有存过路径
{
for(int j=hh[i];j;j=b[j].next)
c[i]=min(c[i],c[b[j].from]+1); //循环它的所有起点,min算出最短路径
if(c[i]>=3)
{
c[i]=0; t++; yd[i]=1; //如果路径大于等于3了就设为医院
}
}
}
printf("%d\n",t);
for(int i=1;i<=n;i++)
if(yd[i]) printf("%d ",i);
return 0;
}