poj:1258
Agri-Net
Time Limit: 1000 MS Memory Limit: 10000 KB
64-bit integer IO format: %I64d , %I64u Java class name: Main
[] [] []
Description
Input
Output
Sample Input
40 4 9 214 0 8 179 8 0 1621 17 16 0
Sample Output
28 题意:N*N个城市 联通全部城市花费的最小代价 eg:0 4 9 2 第二个城市到第一个代价为4 第三个到第一个代价为9 第四个到第一个代价为21 用的Prim
#include#include #include using namespace std;#define INF 100001int t,map[105][105];int prim(){ int sum_dis=0; int m=1,s=1; ///s用来标记选当时中的点 m用来标记选过的点 int point; ///标记当时所在的点 int u[105]= { false}; u[s]=true; int min; int low_dis[105]; for(int i=1; i<=t; i++) low_dis[i]=INF; while(true) { if(t==m) break; min=INF; for(int i=2; i<=t; i++) { if(!u[i]&&low_dis[i]>map[s][i]) low_dis[i]=map[s][i]; ///各点到s点的距离 if(!u[i]&&min>low_dis[i]) { min=low_dis[i]; ///选取最近的到s的距离 point=i; ///记录这一点 } } ///遍历完一行了 sum_dis+=min; s=point; u[s]=true; ///这点找过了 m++; } return sum_dis;}int main(){ while(cin>>t) { for(int i=1; i<=t; i++) { for(int j=1; j<=t; j++) { cin>>map[i][j]; } } cout< <
poj2485
Highways
Time Limit: 1000 MS Memory Limit: 65536 KB
64-bit integer IO format: %I64d , %I64u Java class name: Main
[] [] []
Description
Input
Output
Sample Input
130 990 692990 0 179692 179 0
Sample Output
692
题意: 最小代价走最远路程 样例意思与上一题一样
解析:这次多了一个判断
///走的路最长 花费时间最小#include#include #include using namespace std;#define INF 0x1f1f1f1fint n,a[505][505];int prim(){ ///前提的初始化 int low[65537]; int low_ss; int vis[505]= { false}; int i,j,point,p,s=1,m=1; int min,res=0; vis[s]=true; for(int i=1; i<=n; i++) low[i]=655339; ///进行遍历 while(true) { low_ss=INF; if(n==m) ///同样遍历了全部点 break; for(int i=2; i<=n; i++) { if(!vis[i]&&low[i]>a[s][i]) low[i]=a[s][i]; if(!vis[i]&&low_ss>low[i]) { low_ss=low[i]; point=i; } } if(res
poj1789
Truck History
Time Limit: 2000 MS Memory Limit: 65536 KB
64-bit integer IO format: %I64d , %I64u Java class name: Main
[] [] []
Description
Input
Output
Sample Input
4aaaaaaabaaaaaaabaaaaaaabaaaa0
Sample Output
The highest possible quality is 1/3. 题意:
题意大概是这样的:用一个7位的string代表一个编号,两个编号之间的distance代表这两个编号之间不同字母的个数。一个编号只能由另一个编号“衍生”出来,代价是这两个编号之间相应的distance,现在要找出一个“衍生”方案,使得总代价最小,也就是distance之和最小。
例如有如下4个编号:
aaaaaaa
baaaaaa
abaaaaa
aabaaaa
显然的,第二,第三和第四编号分别从第一编号衍生出来的代价最小,因为第二,第三和第四编号分别与第一编号只有一个字母是不同的,相应的distance都是1,加起来是3。也就是最小代价为3。
问题可以转化为最小代价生成树的问题。因为每两个结点之间都有路径,所以是完全图。
此题的关键是将问题转化为最小生成树的问题。每一个编号为图的一个顶点,顶点与顶点间的编号差即为这条边的权值,题目所要的就是我们求出最小生成树来。这里我用prim算法来求最小生成树。
#include#include #include using namespace std;#define INF 2001int n;char map[INF][7];int dis[INF][INF]= { 0};int weig(int i,int j){ int w=0; for(int k=1; k<=7; k++) { if(map[i][k]!=map[j][k]) w++; } return w;}int prim(){ int m=1,s=1; ///m 遍历过的所有的点 s以后判断其是否走过 int low_dis[INF]; ///每一行中距离该点的距离 int minmin; ///每一行距离该点最近的距离 bool u[2000]= { false}; ///判断是否遍历过 int sum_dis=0; ///最终的最小距离 u[s]=true; int point; ///暂时标记当时遍历的点 for(int i=1;i<=n;i++) low_dis[i]=10; while(1) { if(n==m) break; minmin=10; for(int i=2; i<=n; i++) { if(!u[i]&&low_dis[i]>dis[s][i]) low_dis[i]=dis[s][i]; if(!u[i]&&minmin>low_dis[i]) { minmin=low_dis[i]; point =i; } } sum_dis+=minmin; s=point; u[s]=1; m++; } return sum_dis;}int main(){ while(~scanf("%d",&n)) { if(n==0) break; ///输入部分 for(int i=1; i<=n; i++) for(int j=1; j<=7; j++) cin>>map[i][j]; ///将字符串转化成数字 for(int i=1; i
样例的dis[i][j]==111 2,3,4到1的距离为1 因为就一个字符不同
22 3,4到2的距离为2 因为有两个字符不同
2 4到3的距离为2 因为有两个字符不同 ——————纵向比较即可