小P的图论课 (模拟退火)

uses math;
const maxn=105;
      INF=2000000000;
var n,m,i,x,y,sum,ans,delta:longint;
    map:array[0..maxn,0..maxn] of longint;
    flag:array[0..maxn] of boolean;
    T:double;
    ok:boolean;
function ran:double;
begin
    exit(random(12345)/12345);
end;
procedure add(x,y:longint);
begin
    inc(map[x,0]); map[x,map[x,0]]:=y;
end;
begin
    randomize;
    readln(n,m);
    for i:=1 to m do
    begin
        readln(x,y);
        add(x,y);
        add(y,x);
    end;
    fillchar(flag,sizeof(flag),true);
    T:=0.1;
    sum:=n; ans:=INF;
    while T>0.000001 do
    begin
        T:=T*0.999;
        repeat
            x:=random(n)+1;
        until flag[x];
        delta:=-1;
        for i:=1 to map[x,0] do
        begin
            if map[x,i]=x then inc(delta);
            if not flag[map[x,i]] then inc(delta);
        end;
        ok:=false;
        if delta<0 then ok:=true
        else
            if ran<exp(-delta/T) then ok:=true;
        if ok then
        begin
            sum:=sum+delta;
            if sum<ans then ans:=sum;
            flag[x]:=false;
            for i:=1 to map[x,0] do
                flag[map[x,i]]:=true;
        end;
    end;
    writeln(ans);
end.

 

posted @ 2015-03-30 14:39  rpSebastian  阅读(227)  评论(0编辑  收藏  举报