UVA--10462

解題思路:三種輸出狀況,很簡單,但用prim()寫就WA到底,感受全部狀況都考慮了啊,多是定點不必定是1到N,因此會出現bug.因此建議仍是用kruskal寫簡單一些,別怕超時,大膽寫.spa

kruskal代碼以下:
code

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 110;
const int M = 220;
const int INF = 1000000000;
int n, m, T, ans1, ans2, ise[N], f[N];
struct edge {
    int u, v, cost;
}e[M];

bool cmp( edge a, edge b ) {
    return a.cost < b.cost;
}
int find ( int x ) {
    return f[x] == x ? x: f[x] = find(f[x]);
}
int Kru() {
    int ans = 0, num = 0, id = 0;
    for ( int i = 1; i <= n; ++i ) f[i] = i;
    for ( int i = 0; i < m; ++i ) {
        int x = e[i].u;
        int y = e[i].v;
        int a = find(x);
        int b = find(y);
        if ( a != b ) ise[id++] = i, f[a] = b, ans += e[i].cost;
    }
    for ( int i = 1; i <= n; ++i ) if ( i == find(i) ) num++;
    if ( num > 1 ) return INF;
    else return ans;
}
int Kru_1( int del ) {
    int ans = 0, num = 0;
    for ( int i = 1; i <= n; ++i ) f[i] = i;
    for ( int i = 0; i < m; ++i ) {
        if ( i == del ) continue;
        int x = e[i].u;
        int y = e[i].v;
        int a = find(x);
        int b = find(y);
        if ( a != b ) f[a] = b, ans += e[i].cost;
    }
    for ( int i = 1; i <= n; ++i ) if ( i == find(i) ) num++;
    if ( num > 1 ) return INF;
    else return ans;
}
int main()
{
    int idx = 1;
    scanf("%d", &T);
    while ( T-- ) {
        scanf("%d%d", &n, &m);
        for ( int i = 0; i < m; ++i ) 
            scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].cost);
        sort( e, e+m, cmp );
        ans1 = Kru(), ans2 = INF;
        printf("Case #%d : ", idx++);
        if ( ans1 == INF ) {
            printf("No way\n");
            continue;
        }
        for ( int i = 0; i < n-1; ++i ) {
            int x = ise[i];
            ans2 = min( ans2, Kru_1(x) );
        }
        if ( ans2 == INF ) printf("No second way\n");
        else printf("%d\n", ans2);
    }
    return 0;
}


另外附上我WA的prim():get

</pre><pre name="code" class="cpp">#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
struct stu{
	int x,y,c;
};
stu num[210];
int n,m;
int map[110][110];
int inMST[110][110];
int MST[110][110];
int vis[110];
int per[110];
int low[110];
int see[110][110];
void inin(){
	for(int i=1;i<=n;i++){
	 map[i][i]=0;
		for(int j=1;j<i;j++){
			map[i][j]=map[j][i]=INF;
		}
	}
}
void getMap(){
	int a,b,c;
	memset(see,0,sizeof(see));
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&a,&b,&c);
		num[i].x=a;num[i].y=b;num[i].c=c;
		see[a][b]++;see[b][a]++;
		if(map[a][b]>c){
			map[a][b]=map[b][a]=c;
		}
	}
}
int slove(){
	int temp,v,i,j,k,fa,sum,w,x,y;
	v=0;sum=INF;
	memset(vis,0,sizeof(vis));
	memset(inMST,0,sizeof(inMST));
	memset(MST,0,sizeof(MST));
	for(i=1;i<=n;i++){
		low[i]=map[1][i];
        per[i]=1;
	}
	per[1]=0;
	vis[1]=1;
	for(i=2;i<=n;i++){
		temp=INF;
		for(j=1;j<=n;j++){
			if(!vis[j]&&low[j]<temp){
				temp=low[j];
				k=j;
			}
		}
		if(temp==INF)return -1;
		vis[k]=1;
		v+=temp;
		fa=per[k];
		inMST[k][fa]=inMST[fa][k]=1;
		for(j=1;j<=n;j++){
			if(j!=k&&vis[j])
			MST[k][j]=MST[j][k]=max(MST[j][fa],low[k]);
			if(!vis[j]&&low[j]>map[k][j]){
				low[j]=map[k][j];
				per[j]=k;
			}
			
		}
	}
	for(i=1;i<=m;i++){
		x=num[i].x;y=num[i].y;w=INF;
		if(!inMST[x][y])
			w=v-MST[x][y]+num[i].c;
		else if(see[x][y]>1)
			w=v-map[x][y]+num[i].c;
		if(w<sum)sum=w;	
		
	}
     return sum;
}
int main(){
	int t,ans,k;
	scanf("%d",&t);
	k=1;
	while(t--){
		scanf("%d%d",&n,&m);
		inin();
		getMap();
		ans=slove();
		printf("Case #%d : ",k++);
		if(ans==-1)printf("No way\n");
		else if(ans==INF) printf("No second way\n");
		else  printf("%d\n",ans);
	}
	return 0;
}//錯誤案例 
1
 4 5
1 2 1
1 3 2
3 4 2
4 5 1
5 4 1
錯誤輸出6