Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Задачи по C/С++

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

Открыть новую тему     Написать ответ в эту тему

Ndr3w



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
#include <windows.h>
#include <stdio.h>
#define N 101
 
int v[N][N],u[N][N],
    cross0[N][N];    // 1 - отмеченный ноль, -1 - зачеркнутый.
int str0[N],col0[N];    // Помеченные строки и столбцы.
int strround[N],colround[N];    // Пометка кружками (вторая пометка).
int usestr[N];
int n;            // Размерность матриц.
int vmax=0;        // Максимальный элемент матрицы V.
 
extern char szFileName[200];
 
    // Функция считывания данных из файла.
int read(){
int a;
int i,j;
FILE* potok = fopen(szFileName,"r");
if(!potok){
   MessageBox(0, "Отсутствует файл входных данных!" , "", 16);
   return 0;
   }
fscanf(potok,"%i",&n);
for(i=0; i<n; i++)
   for(j=0; j<n; j++){
      a=fscanf(potok,"%i",&v[i][j]);
      if(a==0 || a==EOF){
         MessageBox(0,"Неверный формат данных!","",16);
         return 0;
         }
      }
fclose(potok);
return 1;
}
 
    // Приведение матрицы
void privod(BOOL ToMax){
int i,j,umin;
for(i=0; i<n; i++)
   for(j=0; j<n; j++)
      vmax = vmax > v[i][j] ? vmax : v[i][j];
if(ToMax){
   for(i=0; i<n; i++)
      for(j=0; j<n; j++)
         u[i][j] = vmax-v[i][j];
   }
else{
   for(i=0; i<n; i++)
      for(j=0; j<n; j++)
         u[i][j] = v[i][j];
   }
for(i=0; i<n; i++){    // Приведение по строкам.
   umin=u[i][0];
   for(j=1; j<n; j++)    // Минимум в строке.
      umin = umin < u[i][j] ? umin : u[i][j];
   for(j=0; j<n; j++)
      u[i][j]-=umin;
   }
for(j=0; j<n; j++){    // Приведение по столбцам.
   umin=u[0][j];
   for(i=1; i<n; i++)    // Минимум в столбце.
      umin = umin < u[i][j] ? umin : u[i][j];
   for(i=0; i<n; i++)
      u[i][j]-=umin;
   }
}
 
void mark0(){    // Отмечаем и зачеркиваем нули.
int i,j;
for(i=0; i<n; i++)
   for(j=0; j<n; j++)
      cross0[i][j]=0;
for(i=0; i<n; i++)
   str0[i]=col0[i]=0;
for(i=0; i<n; i++)
   for(j=0; j<n; j++)
      if(u[i][j]==0)
         if(str0[i]==0 && col0[j]==0){
            cross0[i][j]=1;
            str0[i]=col0[j]=1;
            }
         else
            cross0[i][j]=-1;
}
 
int findcouple(int i){
int i1,j=0;
while(cross0[i][j]!=1) j++;
for(i1=0; i1<n; i1++)
   // Если ноль зачеркнут и в этой строке еще не были
   if(cross0[i1][j]==-1 && !usestr[i1]){
      // Если строка не помечена
      if(!str0[i1]){
         str0[i1]=1;
         cross0[i1][j]=1;
         cross0[i][j]=-1;
         return 1;
         }
      else{
         usestr[i1]=1;
         if(findcouple(i1)){
            cross0[i1][j]=1;
            cross0[i][j]=-1;
            return 1;
            }
         }
      }
return 0;
}
 
    // Нахождение паросочетания.
int upcouple(){
int i,j;
for(i=0; i<n; i++)
   usestr[i]=0;        // В какой строке побывали.
for(j=0; j<n; j++)
   if(!col0[j])
      for(i=0; i<n; i++)
         if(cross0[i][j]==-1){    // Зачеркнутый ноль в непомеченном столбце.
            usestr[i]=1;
            if(findcouple(i)){
               col0[j]=1;
               cross0[i][j]=1;
               return 1;
               }
            else
               usestr[i]=0;
            }
return 0;
}
 
    // Нахождение максимального паросочетания.
void maxcouple(){
while(upcouple());
}
 
    // Проверка на решенность задачи.
int fin(){
int i;
for(i=0; i<n; i++)
   if(!str0[i])
      return 0;
return 1;
}
 
    // Нахождение минимальной опоры.
void minsupport(){
int i,j,b;
for(i=0; i<n; i++)
   strround[i]=colround[i]=0;
for(i=0; i<n; i++)
   strround[i]=1-str0[i];
b=1;
while(b){
   b=0;
   for(i=0; i<n; i++)
      if(strround[i])
         for(j=0; j<n; j++)
            if(cross0[i][j]==-1)
               colround[j]=1;
   for(j=0; j<n; j++)
      if(colround[j])
         for(i=0; i<n; i++)
            if(cross0[i][j]==1 && !strround[i]){
               b=1;
               strround[i]=1;
               }
   }
}
 
    // Перестановка нулей.
void rotate0(){
int i,j,min=vmax;
for(i=0; i<n; i++)
   if(strround[i])
      for(j=0; j<n; j++)
         if(!colround[j])
            if(min>u[i][j])
               min=u[i][j];
for(i=0; i<n; i++)
   if(!strround[i])
      for(j=0; j<n; j++)
         u[i][j]+=min;
for(j=0; j<n; j++)
   if(!colround[j])
      for(i=0; i<n; i++)
         u[i][j]-=min;
}
 
    // Выдача результата в выходной файл.
void answer(BOOL ToMax){
FILE* potok = fopen("output.txt","w");
int i,j;
int sum=0;
fprintf(potok,"           Приказ № ___ от __.__.20__\n");
for(i=0; i<n; i++){
   fprintf(potok,"Назначить %3i-го кандидата ",i+1);
   for(j=0; j<n; j++)
      if(cross0[i][j]==1){
         fprintf(potok,"на %3i-ю должность.\n",j+1);
         sum+=v[i][j];
         break;
         }
   }
if(ToMax)
   fprintf(potok,"\n(Максимальная суммарная эффективность: %i)\n",sum);
else
   fprintf(potok,"\n(Минимальный суммарный вред: %i)\n",sum);
fclose(potok);
}
 
void method(BOOL ToMax){    // ToMax == TRUE  - задача на максимум,
                // ToMax == FALSE  - задача на минимум.
if(!read())
   return;
privod(ToMax);
while(1){
   mark0();
   maxcouple();
   if(fin())
      break;
   minsupport();
   rotate0();
   }
answer(ToMax);
MessageBox(0,"Все просчитано.","См. output.txt",64);
}

Всего записей: 317 | Зарегистр. 11-10-2006 | Отправлено: 22:34 24-12-2007
Открыть новую тему     Написать ответ в эту тему

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Задачи по C/С++


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru